版本更新_版本更新时,如果需要更新的文件正在被程序使用,那么该怎么办? - CSDN
精华内容
参与话题
  • 版本更新

    2018-01-18 15:45:38
    准备工作:请求版本更新获取能下载apk的链接, 比如:”http://yibanyue.oss-cn-hangzhou.xxx.com/apk/yiyue.apk” 流程:请求版本更新链接–>获取到链接,弹框询问是否更新–>在本地建apk文件夹–>更新用Download...

    几乎每个应该都必备的功能
    准备工作:请求版本更新获取能下载apk的链接,
    比如:”http://yibanyue.oss-cn-hangzhou.xxx.com/apk/yiyue.apk
    流程:请求版本更新链接–>获取到链接,弹框询问是否更新–>在本地建apk文件夹–>更新用DownloadManager下载apk,路径放在前面建好的文件夹中–>BroadcastReceiver监听是否下载好,下载完要激活安装
    关键代码
    弹框询问以及建文件夹,下载(无关代码自行删除):
    DOWNLOAD_FOLDER_NAME:apk文件夹名字

    DialogUtils.okAndCancel(mContext, pdesc, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //更新APP
                if (!TextUtils.isEmpty(url)) {
                    downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                    if (isForce) {
                        Dialog dialog = DialogUtils.progress(getContext(), new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                downloadManager.remove(SharedPreferencesUtils.getLong(getContext(), SPKey.APK_DOWN_ID, 0));
                                ActivityUtils.closeAll();
                            }
                        });
                    }
                    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
                    File fileDir = Environment.getExternalStoragePublicDirectory(DOWNLOAD_FOLDER_NAME);
                    if (fileDir.exists() && fileDir.isDirectory()) {
                        request.setDestinationInExternalPublicDir(DOWNLOAD_FOLDER_NAME, url.substring(url.lastIndexOf("/") + 1));
                    } else {
                        fileDir.mkdirs();
                        request.setDestinationInExternalPublicDir(DOWNLOAD_FOLDER_NAME, url.substring(url.lastIndexOf("/") + 1));
                    }
                    long downloadId = downloadManager.enqueue(request);
                    downId = downloadId;
                    SharedPreferencesUtils.saveLong(getContext(), SPKey.APK_DOWN_ID, downloadId);
                } else {
                    toast(R.string.isEmptyUrl);
                }
    
            }
        }, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isForce) {
                    ActivityUtils.closeAll();
                }
            }
        });
    

    下载完激活下载的apk:

    public class DownReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
            DownloadManager.Query query = new DownloadManager.Query();
            //在广播中取出下载任务的id
            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
            query.setFilterById(id);
            Cursor c = manager.query(query);
            if (c.moveToFirst()) {
                //获取文件下载路径
                //Android 7.0以上的方式:请求获取写入权限,这一步报错
    
    
                int fileUriIdx = c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);
                String fileUri = c.getString(fileUriIdx);
                String fileName = null;
                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
                    if (fileUri != null) {
                        fileName = Uri.parse(fileUri).getPath();
                    }
                } else {
                    //过时的方式:DownloadManager.COLUMN_LOCAL_FILENAME
                    int fileNameIdx = c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
                    fileName = c.getString(fileNameIdx);
                }
    
    
                if (id == SharedPreferencesUtils.getLong(context, SPKey.APK_DOWN_ID, 0) && !TextUtils.isEmpty(fileName)) {
                    //打开APK安装
                    installApk(context, fileName);
                } else {
                    //如果文件名不为空,说明已经存在了,拿到文件名想干嘛都好
                    if (fileName != null) {
                        UIUtils.toast(context, R.string.down_success);
                    }
                }
            }
        } else if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(intent.getAction())) {
            long[] ids = intent.getLongArrayExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS);
            //点击通知栏取消下载
            manager.remove(ids);
            UIUtils.toast(context, R.string.down_cancel);
        }
    }
    
    /**
     * 安装APK文件
     */
    public void installApk(Context context, String fileName) {
        ActivityUtils.closeAll();
        File apkfile = new File(fileName);
        if (!apkfile.exists()) {
            return;
        }
        // 通过Intent安装APK文件
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    }}
    

    记得在AndroidMainfest清单中添加:

    <receiver android:name="com.meiguiyuehui.cn.receivers.DownReceiver">
            <intent-filter>
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
                <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" />
            </intent-filter>
        </receiver>
    
    展开全文
  • 版本更新的写法

    2016-09-12 08:29:59
    在maiAcitity里面写public class MainActivity extends Activity { private AlertDialog dialog; private UpdateEntity updateEntity; private TextView tv_name; ... private Handler handler =
    在maiAcitity里面写
    public class MainActivity extends Activity {
    
    	private AlertDialog dialog;
    
    	private UpdateEntity updateEntity;
    
    	private TextView tv_name;
    	/**
    	 * 消息机制
    	 */
    	private Handler handler = new Handler(){
    
    		@Override
    		public void handleMessage(Message msg) {
    			// TODO Auto-generated method stub
    			super.handleMessage(msg);
    
    			switch (msg.what) {
    				case 0:
    					dialog.setMessage(updateEntity.getDescription());
    					dialog.show();
    					break;
    
    				case 1:
    					downLoadApk();
    					break;
    			}
    
    
    		}
    
    	};
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		dialog = new AlertDialog.Builder(MainActivity.this).
    				setTitle("升级提醒").
    				setIcon(R.drawable.ic_launcher).
    				setPositiveButton("在线升级", onclick).
    				setNegativeButton("不想升级", null).
    				create();
    
    
    
    		//开启线程
    		new Thread(new CheckVersionTask()).start();
    	}
    
    	DialogInterface.OnClickListener  onclick = new DialogInterface.OnClickListener(){
    
    		@Override
    		public void onClick(DialogInterface dialog, int which) {
    			// TODO Auto-generated method stub
    			handler.sendEmptyMessage(1);
    		}
    
    	};
    
    	/*
    	 * 从服务器中下载APK
    	 */
    	protected void downLoadApk() {
    		final ProgressDialog pd;    //进度条对话框
    		pd = new  ProgressDialog(this);
    		pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    		pd.setMessage("正在下载更新");
    		pd.show();
    		new Thread(){
    			@Override
    			public void run() {
    				try {
    					File file =  getFileFromServer(updateEntity.getUrl(), pd);
    					sleep(3000);
    
    					UpdateTools tools = new UpdateTools();
    					//安装APk
    					tools.installApk(file,MainActivity.this);
    					pd.dismiss(); //结束掉进度条对话框
    
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}}.start();
    	}
    
    	/*
    	 * 从服务器获取xml解析并进行比对版本号
    	 */
    	public class CheckVersionTask implements Runnable{
    
    		public void run() {
    			try {
    				//从资源文件获取服务器 地址
    				String path = getResources().getString(R.string.serverurl);
    				//包装成url的对象
    				URL url = new URL(path);
    				HttpURLConnection conn =  (HttpURLConnection) url.openConnection();
    				conn.setConnectTimeout(5000);
    				InputStream is =conn.getInputStream();
    				updateEntity =  UpdateTools.getUpdataInfo(is);
    
    				int versionCode = MainActivity.this.getPackageManager().getPackageInfo(MainActivity.this.getPackageName(), 0).versionCode;
    
    				if(Integer.parseInt(updateEntity.getVersion()) <= versionCode){
    					Log.i("xxx","版本号相同无需升级");
    				}else{
    					Log.i("xxxx","版本号不同 ,提示用户升级 ");
    					handler.sendEmptyMessage(0);
    
    				}
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    	/**
    	 * 下载方法
    	 *
    	 * @param path
    	 * @param pd
    	 * @return
    	 * @throws Exception
    	 */
    	public File getFileFromServer(String path, ProgressDialog pd)
    			throws Exception {
    		// 如果相等的话表示当前的sdcard挂载在手机上并且是可用的
    		if (Environment.getExternalStorageState().equals(
    				Environment.MEDIA_MOUNTED)) {
    			URL url = new URL(path);
    			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    			conn.setConnectTimeout(5000);
    			// 获取到文件的大小
    			pd.setMax(conn.getContentLength());
    			InputStream is = conn.getInputStream();
    			File file = new File(Environment.getExternalStorageDirectory(),
    					"updata.apk");
    			FileOutputStream fos = new FileOutputStream(file);
    			BufferedInputStream bis = new BufferedInputStream(is);
    			byte[] buffer = new byte[1024];
    			int len;
    			int total = 0;
    			while ((len = bis.read(buffer)) != -1) {
    				fos.write(buffer, 0, len);
    				total += len;
    				// 获取当前下载量
    				pd.setProgress(total);
    			}
    			fos.close();
    			bis.close();
    			is.close();
    			return file;
    		} else {
    			return null;
    		}
    	}
    
    	@Override
    	protected void onPause() {
    		Log.w(Conf.TAG, "Activity1.onPause()");
    		// TODO Auto-generated method stub
    		super.onPause();
    
    	}
    
    	@Override
    	protected void onResume() {
    		Log.w(Conf.TAG, "Activity1.onResume()");
    		// TODO Auto-generated method stub
    		super.onResume();
    
    	}
    
    
    }
    

    UpdateEntity类写法:

    /**
     * 版本更新信息的封装
     *
     * @author dagang
     *
     */
    public class UpdateEntity {
    	private String version;
    
    	private String url;
    
    	private String description;
    
    	public String getVersion() {
    		return version;
    	}
    
    	public void setVersion(String version) {
    		this.version = version;
    	}
    
    	public String getUrl() {
    		return url;
    	}
    
    	public void setUrl(String url) {
    		this.url = url;
    	}
    
    	public String getDescription() {
    		return description;
    	}
    
    	public void setDescription(String description) {
    		this.description = description;
    	}
    
    
    
    
    
    }
    UpdateTools类写法

    /**
     *
     * 获取服务器的更新内容
     *
     * 当前版本
     *
     * apk的路径
     *
     * 更新细则
     *
     * @author dagang
     *
     */
    public class UpdateTools {
    	/*
    	 * 用pull解析器解析服务器返回的xml文件 (xml封装了版本号)
    	 */
    	public static UpdateEntity getUpdataInfo(InputStream is) throws Exception {
    		XmlPullParser parser = Xml.newPullParser();
    		parser.setInput(is, "utf-8");// 设置解析的数据源
    		int type = parser.getEventType();
    		UpdateEntity info = new UpdateEntity();// 实体
    		while (type != XmlPullParser.END_DOCUMENT) {
    			switch (type) {
    				case XmlPullParser.START_TAG:
    					if ("version".equals(parser.getName())) {
    						info.setVersion(parser.nextText()); // 获取版本号
    					} else if ("url".equals(parser.getName())) {
    						info.setUrl(parser.nextText()); // 获取要升级的APK文件
    					} else if ("description".equals(parser.getName())) {
    						info.setDescription(parser.nextText()); // 获取该文件的信息
    					}
    					break;
    			}
    			type = parser.next();
    		}
    		return info;
    	}
    
    	/**
    	 *
    	 * 安装Apk
    	 *
    	 * @param file
    	 * @param context
    	 */
    	public void installApk(File file,Context context) {
    		Intent intent = new Intent();
    		//执行动作
    		intent.setAction(Intent.ACTION_VIEW);
    		//执行的数据类型
    		intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
    		context.startActivity(intent);
    	}
    }
    
    在value里面的string添加:
      <!-- 版本更新 -->
        <string name="serverurl">http://169.254.172.144:8080/goods_file/update_file.xml</string>




    展开全文
  • Android 版本更新

    千次阅读 2019-04-16 11:08:29
    版本更新这一块涉及的知识点比较少,但也花了一天时间,仅做记录用,为了方便大家理解,我画了一张流程图。需求比较简单,以后可以根据产品需求适当更改。 以下版本更新工具类 /** * Created by minmin.shen ...

    摘要

    版本更新这一块涉及的知识点比较少,但也花了一天时间,仅做记录用,为了方便大家理解,我画了一张流程图。需求比较简单,以后可以根据产品需求适当更改。

    版本
    以下版本更新工具类

    /**
     * Created by minmin.shen
     * on 2019/1/23
     * 检查更新版本工具类
     */
    public class UpdateManager {
        private String downLoadPath = "";
        private String url = "";//apk下载地址
        private boolean isforce = false;
        private String oldApkName = "";
        private String newApkName = "";
        private Context context;
    
        private BaseDialog updataDialog;
        private BaseDialog installDialog;
        private ProgressDialog progressDialog;
        private FragmentManager fm;
        public static UpdateManager updateManager;
    
        public static UpdateManager getInstance() {
            if (updateManager == null) {
                updateManager = new UpdateManager();
            }
            return updateManager;
        }
    
        public void start(){
            if(checkIsHaveNewAPK()){
                showInstallDialog("发现新版本,是否安装?");
            }else{
                showUpdataDialog();
            }
        }
    
        /**
         * 版本更新提示框
         */
        public void showUpdataDialog() {
            updataDialog = BaseDialog.getInstance().setTitle("提示").setContent("发现新版本,是否更新?")
                    .setPositionText("取消", new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            updataDialog.dismiss();
                            if (isforce) {
                                System.exit(0);
                            }
                        }
                    })
                    .setNegativeText("更新", new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            updataDialog.dismiss();
                            createProgress(context);
                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    downloadApk();
                                }
                            }).start();
    
                        }
                    });
            updataDialog.show(fm, "dialog for update");
        }
    
        /**
         * 弹出安装Dialog
         */
        private void showInstallDialog(String content){
            installDialog = BaseDialog.getInstance().setTitle("提示").setContent(content)
                    .setPositionText("取消", new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            installDialog.dismiss();
                            if (isforce) {
                                System.exit(0);
                            }
                        }
                    })
                    .setNegativeText("安装", new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            installDialog.dismiss();
                            File fileAPK = new File(downLoadPath, newApkName);
                            installApk(context, fileAPK);
                        }
                    });
            installDialog.show(fm, "dialog for install");
        }
    
        /**
         * 检查有没有最新的APK
         */
        private boolean checkIsHaveNewAPK(){
            File file = new File(downLoadPath);
            if (!file.exists()) {
                file.mkdirs();
            }
            File fileAPK = new File(downLoadPath, newApkName);
            if(fileAPK.exists()){
                return true;
            }
            return false;
        }
    
        /**
         * 删除旧的apk
         */
        private void delOldApk(){
            File fileAPK = new File(downLoadPath, oldApkName);
            if(fileAPK.exists()){
                fileAPK.delete();
            }
        }
    
        /**
         * 下载APK
         */
        private void downloadApk() {
            try {
                final long startTime = System.currentTimeMillis();
                Log.i("DOWNLOAD", "startTime=" + startTime);
                //获取文件名
                URL myURL = new URL(url);
                URLConnection conn = myURL.openConnection();
                conn.connect();
                InputStream is = conn.getInputStream();
                int fileSize = conn.getContentLength();//根据响应获取文件大小
                Log.i("DOWNLOAD", "总大小="+fileSize);
                if (fileSize <= 0) throw new RuntimeException("无法获知文件大小 ");
                if (is == null) throw new RuntimeException("stream is null");
                File file1 = new File(downLoadPath);
                if (!file1.exists()) {
                    file1.mkdirs();
                }
                //把数据存入路径+文件名
                FileOutputStream fos = new FileOutputStream(downLoadPath + "/" + newApkName);
                byte buf[] = new byte[1024];
                int downLoadFileSize = 0;
                do {
                    //循环读取
                    int numread = is.read(buf);
                    if (numread == -1) {
                        break;
                    }
                    fos.write(buf, 0, numread);
                    downLoadFileSize += numread;
                    Log.i("DOWNLOAD", "downLoadFileSize="+downLoadFileSize);
                    Log.i("DOWNLOAD", "fileSize="+fileSize);
                    Log.i("DOWNLOAD", "download downLoadFileSize="+(int)((float)downLoadFileSize*100/fileSize));
                    progressDialog.setProgress((int)((float)downLoadFileSize*100/fileSize));
                    //更新进度条
                } while (true);
                delOldApk();
                progressDialog.dismiss();
                showInstallDialog("下载完成,是否安装?");
                Log.i("DOWNLOAD", "download success");
                Log.i("DOWNLOAD", "totalTime=" + (System.currentTimeMillis() - startTime));
                is.close();
            } catch (Exception ex) {
                Log.e("DOWNLOAD", "error: " + ex.getMessage(), ex);
            }
        }
    
        /**
         * 强制更新时显示在屏幕的进度条
         */
        private void createProgress(Context context) {
            progressDialog = new ProgressDialog(context);
            progressDialog.setMax(100);
            progressDialog.setCancelable(false);
            progressDialog.setMessage("正在下载...");
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.show();
        }
    
        /**
         * 安装apk
         */
        private void installApk(Context context, File file) {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            //判断是否是AndroidN以及更高的版本
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                Uri contentUri = FileProvider.getUriForFile(context, "com.baozun.book.fileProvider", file);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
            } else {
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
            }
            context.startActivity(intent);
        }
    
        /**
         * apk网络地址
         */
        public UpdateManager setContext(Context context) {
            this.context = context;
            return this;
        }
    
        /**
         * apk网络地址
         */
        public UpdateManager setUrl(String url) {
            this.url = url;
            return this;
        }
    
        /**
         * 新版本文件名
         */
        public UpdateManager setNewFileName(String fileName) {
            this.newApkName = fileName;
            return this;
        }
    
        /**
         * 旧版本文件名
         */
        public UpdateManager setOldFileName(String fileName) {
            this.oldApkName = fileName;
            return this;
        }
    
        /**
         * Fragment管理器
         */
        public UpdateManager setFragmentManager(FragmentManager fm) {
            this.fm = fm;
            return this;
        }
    
        /**
         * 下载路径
         */
        public UpdateManager setDownloadPath(String downLoadPath) {
            this.downLoadPath = downLoadPath;
            return this;
        }
    
        /**
         * 是否强制更新
         */
        public UpdateManager setIsforce(boolean isforce) {
            this.isforce = isforce;
            return this;
        }
    
    }
    

    下面是发起调用

    public static void checkUpdate(Context context, android.support.v4.app.FragmentManager fm, float versionCode, String url, boolean isForced) {
       if (versionCode > Float.parseFloat(Util.getCurrentVersionName(context))) {
          String downLoadPath = context.getExternalFilesDir(null).toString() + "/download/";
               String newFileName = "U_Reading"+versionCode+".apk";
          String oldFileName = "U_Reading"+Float.parseFloat(Util.getCurrentVersionName(context))+".apk";
    
          //设置参数
          UpdateManager.getInstance()
                .setContext(context)
                .setFragmentManager(fm)
                .setDownloadPath(downLoadPath)
                .setNewFileName(newFileName)
                .setOldFileName(oldFileName)
                .setUrl(url)
                .setIsforce(isForced)
                .start();
       }
    }
    

    其中安装apk需要注意下,在manifest文件中加入代码

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.baozun.book.fileProvider"
        android:grantUriPermissions="true"
        android:exported="false">
                 
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"/>
    </provider>
    

    在这里插入图片描述
    在资源文件中加入

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <external-path
            name="files_root"
            path="Android/data/com.baozun.book/" />
                     
        <external-path
            name="external_storage_root"
            path="." />
    </paths>
    

    先简单写一下,待详细整理

    ---------------------------------------------------------------2019/4/16号更新----------------------------------------------------------------

    近期发现代码安装APK的时候,在华为手机上不会弹出安装界面

    需要在清单文件中配置权限

    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    
    展开全文
  • 软件发布版本更新

    千次阅读 2019-06-02 21:55:53
    一、 版本号自动生成方法 1.把 AssemblyInfo.cs文件中的[assembly:AssemblyVersion("1.0.0.0")]改成[assembly:AssemblyVersion("1.0.*")] 2.把[assembly:AssemblyFileVersion("1.0.0.0")]注释掉。这样再生成的程序...

    一、 版本号自动生成方法

    1.把 AssemblyInfo.cs文件中的[assembly:AssemblyVersion("1.0.0.0")]改成[assembly:AssemblyVersion("1.0.*")]

    2.把[assembly:AssemblyFileVersion("1.0.0.0")]注释掉。这样再生成的程序集就是自动版本号了。

    按照这个格式出来的版本号,内部修订版本号(第三个字段)的位置出现的是2000年1月1日到编译日期的天数,内部修订号(第四个字段)是当天从0点到当前时间的刻度数。

    二、 Window 下的版本号管理策略:

    1.目初版时 , 版本号为 1.0 或 1.00;
    2. 当项目在进行了局部修改或 bug 修正时,主版本号和子版本号都不变 , 修正版本号加 1;
    3. 当项目在原有的基础上增加了部分功能时 , 主版本号不变 , 子版本号加 1, 修正版本号复位为 0, 因而可以被忽略掉 ;
    4. 当项目在进行了重大修改或局部修正累积较多 , 而导致项目整体发生全局变化时 , 主版本号加 1;
    5. 另外 , 编译版本号一般是编译器在编译过程中自动生成的 , 我们只定义其格式 , 并不进行人为控制 .

    另外 , 还可以在版本号后面加入 Alpha, Beta, Gamma, Current, RC (Release
    Candidate), Release, Stable 等后缀 , 在这后缀后面还可以加入 1 位数字的版本号 .

    对于用户来说 , 如果某个软件的主版本号进行了升级 , 用户还想继续那个软件 , 则发行软件的公司一般要对用户收取升级费用 ; 而如果子版本号或修正版本号发生了升级 , 一般来说是免费的 .

    附: alphal 内部测试版
    beta 外部测试版
    demo 演示版
    Enhance 增强版或者加强版 属于正式版
    Free 自由版
    Full version 完全版 属于正式版
    shareware 共享版
    Release 发行版
    有时间限制
    Upgrade 升级版
    Retail 零售版
    Cardware 属共享软件的一种,只要给作者回复一封电邮或明信片即可。(有的作者并由此提供注册码等),目前这种形式已不多见。
    Plus 属增强版,不过这种大部分是在程序界面及多媒体功能上增强。
    Preview 预览版
    Corporation & Enterprise 企业版
    Standard 标准版
    Mini 迷你版也叫精简版只有最基本的功能
    Premium

    — 正式版
    Professional — 专业版
    Express — 特别版
    Deluxe — 豪华版
    Regged — 已注册版
    CN — 简体中文版
    CHT — 繁体中文版
    EN — 英文版
    Multilanguage — 多语言版

    注释:

    α版

    此版本表示该软件仅仅是一个初步完成品,通常只在软件开发者内部交流,也有很少一部分发布给专业测试人员。一般而言,该版本软件的 bug 较多,普通用户最好不要安装。

    β(beta)版

    该版本相对于α版已有了很大的改进,消除了严重的错误,但还是存在着一些缺陷,需要经过大规模的发布测试来进一步消除。这一版本通常由软件公司免费
    发 布,用户可从相关的站点下载。通过一些专业爱好者的测试,将结果反馈给开发者,开发者们再进行有针对性的修改。该版本也不适合一般用户安装。

    γ版

    该版本已经相当成熟了,与即将发行的正式版相差无几,如果用户实在等不及了,尽可以装上一试。

    trial(试用版)

    试用版软件在最近的几年里颇为流行,主要是得益于互联网的迅速发展。该版本软件通常都有时间限制,过期之后用户如果希望继续使用,一般得交纳一定的费用进行注册或购买。有些试用版软件还在功能上做了一定的限制。

    unregistered(未注册版)

    未注册版与试用版极其类似,只是未注册版通常没有时间限制,在功能上相对于正式版做了一定的限制,例如绝大多数网络电话软件的注册版和未注册版,两
    者 之间在通话质量上有很大差距。还有些虽然在使用上与正式版毫无二致,但是动不动就会弹出一个恼人的消息框来提醒你注册,如看图软件 acdsee 、智能陈桥汉字输入软件等。

    demo版

    也称为演示版,在非正式版软件中,该版本的知名度最大。 demo 版仅仅集成了正式版中的几个功能,颇有点像 unregistered 。不同的是, demo 版一般不能通过升级或注册的方法变为正式版。

    以上是软件正式版本推出之前的几个版本,α、β、γ可以称为测试版,大凡成熟软件总会有多个测试版,如 windows 98 的β版,前前后后将近有 10 个。这么多的测试版一方面为了最终产品尽可能地满足用户的需要,另一方面也尽量减少了软件中的 bug 。而 trial 、 unregistered 、 demo 有时统称为演示版,这一类版本的广告色彩较浓,颇有点先尝后买的味道,对于普通用户而言自然是可以免费尝鲜了。

    正式版 不同类型的软件的正式版本通常也有区别。

    release

    该版本意味“最终释放版”,在出了一系列的测试版之后,终归会有一个正式版本,对于用户而言,购买该版本的软件绝对不会错。该版本有时也称为标准
    版。 一般情况下, release 不会以单词形式出现在软件封面上,取而代之的是符号 (r) ,如 windows nt(r) 4.0 、 ms-dos(r) 6.22 等。

    registered

    很显然,该版本是与 unregistered 相对的注册版。注册版、 release 和下面所讲的 standard 版一样,都是软件的正式版本,只是注册版软件的前身有很大一部分是从网上下载的。

    standard

    这是最常见的标准版,不论是什么软件,标准版一定存在。标准版中包含了该软件的基本组件及一些常用功能,可以满足一般用户的需求。其价格相对高一级版本而言还是“平易近人”的。

    deluxe

    顾名思义即为“豪华版”。豪华版通常是相对于标准版而言的,主要区别是多了几项功能,价格当然会高出一大块,不推荐一般用户购买。此版本通常是为那些
    追求“完美”的专业用户所准备的。

    reference

    该版本型号常见于百科全书中,比较有名的是微软的 encarta 系列。 reference 是最高级别,其包含的主题、图像、影片剪辑等相对于 standard 和 deluxe 版均有大幅增加,容量由一张光盘猛增至三张光盘,并且加入了很强的交互功能,当然价格也不菲。可以这么说,这一版本的百科全书才能算是真正的百科全书,也是发烧友们收藏的首选。

    professional(专业版)

    专业版是针对某些特定的开发工具软件而言的。专业版中有许多内容是标准版中所没有的,这些内容对于一个专业的软件开发人员来说是极为重要的。如微软
    的 visual foxpro 标准版并不具备编译成可执行文件的功能,这对于一个完整的开发项目而言显然是无法忍受的,若客户机上没有 foxpro 将不能使用。如果用专业版就没有这个问题了。

    enterprise(企业版)

    企业版是开发类软件中的极品(相当于百科全书中的 reference 版)。拥有一套这种版本的软件可以毫无障碍地开发任何级别的应用软件。如著名的 visual c++ 的企业版相对于专业版来说增加了几个附加的特性,如 sql 调试、扩展的存储过程向导、支持 as/400 对 ole db 的访问等。而这一版本的价格也是普通用户无法接受的。如微软的 visual studios 6.0 enterprise 中文版的价格为 23000 元。

    其他版本 除了以上介绍的一些版本外,还有一些专有版本名称。

    update(升级版)

    升级版的软件是不能独立使用的,该版本的软件在安装过程中会搜索原有的正式版,如果不存在,则拒绝执行下一步。如 microsoft office 2000 升级版、 windows 9x 升级版等等。

    OEM版

    OEM版通常是捆绑在硬件中而不单独销售的版本。将自己的产品交给别的公司去卖,保留自己的著作权,双方互惠互利,一举两得。

    单机(网络)版

    网络版在功能、结构上远比单机版复杂,如果留心一下软件的报价,你就会发现某些软件单机版和网络版的价格相差非常大,有些网络版甚至多一个客户端口就要加不少钱。

    普及版

    该版本有时也会被称为共享版,其特点是价格便宜(有些甚至完全免费)、功能单一、针对性强(当然也有占领市场、打击盗版等因素)。与试用版不同的是,该版本的软件一般不会有时间上的限制。当然,如果用户想升级,最好还是去购买正式版。

    此随笔或为自己所写、或为转载于网络。仅用于个人收集及备忘。

    https://www.cnblogs.com/shy1766IT/p/6221557.html

    展开全文
  • app版本更新的四种实现方式

    万次阅读 2020-09-24 10:41:14
    版本更新大致分为四大类: 1.app负责单版本检测测与更新(自己实现版本更新); 2.通过苹果商店的自动更新机制进行自动更新(相当与自己不更新,靠苹果商店自己的自动更新机制更新,这个是苹果提倡的升级机制,但是app...
  • vue更新版本

    万次阅读 2018-07-31 15:36:54
    cnpm install -g @vue/cli
  • R | 如何更新R版本及Rstudio

    万次阅读 2019-07-27 23:29:02
    文章目录Windows下更新R版本及Rstudio一、更新R版本二、Rstudio中更新R Windows下更新R版本及Rstudio 在R中安装一些包时,经常会出现包与旧版本R不兼容的问题,所以就对Windows下R的版本进行了更新(Version 3.4.4—...
  • 如何将pip更新到最新版本?

    万次阅读 2018-04-15 19:35:18
    #我是用的python36!!!!如何将pip更新到最新版本?只用使用命令如下就可以更新了。[html] view plain copypython -m pip install --upgrade pip 
  • 如何更新npm至最新版本

    万次阅读 多人点赞 2016-10-28 13:18:39
    去年曾遇到过执行npm某项命令时提示要求更高版本的npm,当时百度解决了,今天又再次遇到该问题。现记下来,以供以后参考。命令行运行:npm install -g npmnpm就自动为我们更新到最新版本
  • Intellij Idea 使用SVN更新到指定版本

    万次阅读 2016-03-22 17:25:48
    使用问题默认情况下,changes视图,在Incoming中更新任意版本,整个项目都会被更新。这样会导致的更新到很多不应该更新的版本。...选择Update Project,进入版本更新选择项界面。勾选Update/Switch to speci
  • python的pip如何更新到最新版本

    万次阅读 多人点赞 2016-12-09 20:28:40
    如何将pip更新到最新版本? 只用使用命令如下就可以更新了。 python -m pip install --upgrade pip
  • npm 版本更新指令

    万次阅读 2018-01-04 15:05:50
    如果我们的npm安装版本较旧,现在需要更新应该怎么操作呢? 首先查看当前版本,在win下输入$ npm -v 之后输入$ npm install npm@latest -g 进行npm版本自动更新
  • anaconda升级sklearn版本

    万次阅读 2020-09-20 17:36:28
    经过检查,发现anaconda中的sklearn版本太低,为0.17版本。于是,开始了sklearn的升级之旅。1.查看原有版本首先使用conda list命令,查看一下现有的版本: 果不其然,版本是0.17.1,版本太低,果断开始升级。2.升级...
  • 更新npm至最新版本

    万次阅读 2018-09-03 11:00:40
    今天要安装Ionic CLI,要求是 “在继续之前,请确保安装了最新版本的Node.js和npm。” 我目前的npm版本是 使用命令 npm install -g npm 升级之后
  • 一条命令更新composer版本

    万次阅读 2019-08-20 13:08:49
    composer self-update
  • Python更新PIP至最新版本

    万次阅读 2018-08-02 10:20:30
    有时我们使用pip为python安装模块“python -m pip install **”时,系统提醒需要更新pip版本,使用以下指令即可: python -m pip install --upgrade pip
  • 如何将npm升级到最新版本

    万次阅读 2018-06-13 09:22:02
    查看当前版本 npm -v更新到最新版本 npm install -g npm更新到指定版本 npm -g install npm@5.6.0 (@后面加指定版本号)啦啦啦~~希望能帮到小伙伴们呦
  • 利用Rstudio升级R语言版本

    万次阅读 2018-01-24 11:42:51
    install.packages("installr") library(installr) updateR()
  • 如何使用Anaconda更新Python版本

    万次阅读 2018-09-11 09:47:13
    cmd中输入conda update python就行了。
  • 更新pip到指定版本

    万次阅读 2018-08-20 18:21:44
    python3 -m pip install --user --upgrade pip==9.0.3(换成你想要的版本编号)
1 2 3 4 5 ... 20
收藏数 1,452,046
精华内容 580,818
关键字:

版本更新