C說話中char*和char[]用法差別剖析。本站提示廣大學習愛好者:(C說話中char*和char[]用法差別剖析)文章只能為提供參考,不一定能成為您想要的結果。以下是C說話中char*和char[]用法差別剖析正文
開辟中對版本停止檢討並更新的需求根本是一切運用必需有的功效,可是在現實開辟中有些同伙就輕易疏忽一些細節。
版本更新的根本流程:
普通是將當地版本告知辦事器,辦事器經由相干處置會前往客戶端相干信息,告知客戶端需不須要更新,假如須要更新是強迫更新照樣非強迫更新。客戶端獲得辦事器前往的相干信息後再進一步做邏輯處置。
強迫更新:
普通的處置就是進入運用就彈窗告訴用戶有版本更新,彈窗可以沒有撤消按鈕其實不能撤消。如許用戶就只能選擇更新或許封閉運用了,固然也能夠添加撤消按鈕,然則假如用戶選擇撤消則直接加入運用。
非強迫更新
普通的處置是在運用的設置中添加版本檢討的操作,假如用戶自動檢討版本則彈窗告訴用戶有版本更新。這時候用戶可以撤消或許更新。
功效現實是比擬簡略清楚的,但之所以寫這篇文章,是由於在我們公司的一個項目中,我把這個模塊分給了一個有著4年任務經歷的哥們編寫,最初這哥們花了2個小時做完了。我還想這哥們寫得挺快,效力很高嘛,成果一測試發明成績很多:
1. 進入首頁前封閉收集,進入後刷新界面發明強迫更新提示沒有彈窗
2. 再進入其它界面也沒有任何更新提示
3. 在正常更新時點擊肯定更新,沒有斷定收集狀況(wifi,挪動收集)直接下載apk文件,假如用戶在挪動收集下將消耗異常多的流量,直接影響用戶體驗
4. 下載進程在運用內沒有進度條提示,告訴欄也沒有進度提示
5. apk文件下載進程中,假如強迫停止運用,下載被中止
6. apk假如正常下載上去,彈出了裝置界面,這時候假如用戶撤消了裝置回到運用,在須要強迫更新的情形下並沒有再次彈窗阻攔用戶停止任何其它操作,掉去了強迫更新的意義
起首聲明下,我這涓滴沒有吐槽的意思喲,只是想說作為一個及格的法式員年夜家最最少須要做到思想嚴謹這點,在有才能的情形下對用戶體驗能提點建議最好。本身寫的代碼必定要經由嚴厲測試再交付,不要期望測試人員幫你測試再去修正,你要曉得如今許多公司是沒有專業的測試人員乃至是沒有測試人員的喲。
針對以上成績湧現的緣由剖析及處理計劃以下:
關於1,2成績
很顯著他把檢討更新的任務只寫在了運用的首頁(好比MainActivity)中了,在其它任何界面並沒有檢討更新的操作
處理計劃
每一個界面都須要檢討更新,固然我們不克不及在每一個Activity中都復制粘貼一樣的代碼。這時候界說一個BaseActivity,一切其它Activity都從它繼續就顯得很有價值了。可以把檢討更新的操作放到BaseActivity的相干辦法中,好比放在onResume中,如許每當顯示一個界面時都將履行檢討更新的操作
關於5成績,假如把下載的操作放在了Activity中停止,假如運用不測終止或許強迫加入運用,則下載線程也將被終止
處理計劃
可以將下載義務放到Service中履行,如許即便運用被終止Service一樣有保活機制(startForeground)讓Service的義務有很年夜的機遇持續得以履行
關於6成績,假如檢討更新的操作沒有在Activity的resume時再次履行,則回到Activity天然也就沒有檢討更新並彈窗了
處理計劃
在Activity的onResume中持續檢討更新,假如是強迫更新則彈窗阻攔用戶停止其它操作
關於3,4成績,我卻是認為不是法式成績而是立場成績,現實參加非wifi和進度顯示的功效異常簡略
全體處理計劃
界說Service類,好比VersionUpdateService.java。重要供給版本檢討及文件下載操作
界說VersionUpdateHelper類,用來應用Service並供給和前台Activity的交互
假如年夜家對Service的應用還有成績(須要頻仍更新前台ui等),建議年夜家浏覽android圖片緊縮上傳系列-service篇這篇文章先做懂得。
焦點代碼以下:
public class VersionUpdateService extends Service {
private LocalBinder binder = new LocalBinder();
private DownLoadListener downLoadListener;//下載義務監聽回調接口
private boolean downLoading;
private int progress;
private NotificationManager mNotificationManager;
private NotificationUpdaterThread notificationUpdaterThread;
private Notification.Builder notificationBuilder;
private final int NOTIFICATION_ID = 100;
private VersionUpdateModel versionUpdateModel;
private CheckVersionCallBack checkVersionCallBack;//檢討成果監聽回調接口
public interface DownLoadListener {
void begain();
void inProgress(float progress, long total);
void downLoadLatestSuccess(File file);
void downLoadLatestFailed();
}
public interface CheckVersionCallBack {
void onSuccess();
void onError();
}
...
private class NotificationUpdaterThread extends Thread {
@Override
public void run() {
while (true) {
notificationBuilder.setContentTitle("正鄙人載更新" + progress + "%"); // the label of the entry
notificationBuilder.setProgress(100, progress, false);
...
}
}
}
private void starDownLoadForground() {
//創立告訴欄
notificationBuilder = new Notification.Builder(this);
...
Notification notification = notificationBuilder.getNotification();
startForeground(NOTIFICATION_ID, notification);
}
private void stopDownLoadForground() {
stopForeground(true);
}
//履行版本檢討義務
public void doCheckUpdateTask() {
//獲得本定版本號
final int currentBuild = AppUtil.getVersionCode(this);
//挪用版本檢討接口
ApiManager.getInstance().versionApi.upgradeRecords(currentBuild, new RequestCallBack() {
@Override
public void onSuccess(Headers headers, String response) {
versionUpdateModel = JSON.parseObject(response, VersionUpdateModel.class);
...
if (checkVersionCallBack != null)
checkVersionCallBack.onSuccess();
}
@Override
public void onError(int code, String response) {
...
}
});
}
public void doDownLoadTask() {
starDownLoadForground();
//啟動告訴欄進度更新線程
notificationUpdaterThread = new NotificationUpdaterThread();
notificationUpdaterThread.start();
//文件下載寄存途徑
final File fileDir = FolderUtil.getDownloadCacheFolder();
...
downLoading = true;
if (downLoadListener != null) {
downLoadListener.begain();
}
NetManager.getInstance().download(url, fileDir.getAbsolutePath(), new DownloadCallBack() {
@Override
public void inProgress(float progress_, long total) {
...
//履行進度更新
if (downLoadListener != null)
downLoadListener.inProgress(progress_, total);
}
@Override
public void onSuccess(Headers headers, String response) {
//履行勝利回調
...
installApk(destFile, VersionUpdateService.this);
}
@Override
public void onError(int code, String response) {
...
//履行掉敗回調
}
});
}
//裝置apk
public void installApk(File file, Context context) {
...
}
}
public class VersionUpdateHelper implements ServiceConnection {
private Context context;
private VersionUpdateService service;
private AlertDialog waitForUpdateDialog;
private ProgressDialog progressDialog;
private static boolean isCanceled;
private boolean showDialogOnStart;
public static final int NEED_UPDATE = 2;
public static final int DONOT_NEED_UPDATE = 1;
public static final int CHECK_FAILD = -1;
public static final int USER_CANCELED = 0;
private CheckCallBack checkCallBack;
public interface CheckCallBack{
void callBack(int code);
}
public VersionUpdateHelper(Context context) {
this.context = context;
}
public void startUpdateVersion() {
if (isCanceled)
return;
if (isWaitForUpdate() || isWaitForDownload()) {
return;
}
if (service == null && context != null) {
context.bindService(new Intent(context, VersionUpdateService.class), this, Context.BIND_AUTO_CREATE);
}
}
public void stopUpdateVersion() {
unBindService();
}
private void cancel() {
isCanceled = true;
unBindService();
}
private void unBindService() {
if (isWaitForUpdate() || isWaitForDownload()) {
return;
}
if (service != null && !service.isDownLoading()) {
context.unbindService(this);
service = null;
}
}
...
private void showNotWifiDownloadDialog() {
final AlertDialog.Builder builer = new AlertDialog.Builder(context);
builer.setTitle("下載新版本");
builer.setMessage("檢討到您的收集處於非wifi狀況,下載新版本將消費必定的流量,能否持續下載?");
builer.setNegativeButton("今後再說", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
...
//假如是強迫更新 exit app
if (mustUpdate) {
MainApplication.getInstance().exitApp();
}
}
});
builer.setPositiveButton("持續下載", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
service.doDownLoadTask();
}
});
...
}
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
service = ((VersionUpdateService.LocalBinder) binder).getService();
service.setCheckVersionCallBack(new VersionUpdateService.CheckVersionCallBack() {
@Override
public void onSuccess() {
VersionUpdateModel versionUpdateModel = service.getVersionUpdateModel();
//EventBus掌握更新紅點提醒
EventBus.getDefault().postSticky(versionUpdateEvent);
if (!versionUpdateModel.isNeedUpgrade()) {
if(checkCallBack != null){
checkCallBack.callBack(DONOT_NEED_UPDATE);
}
cancel();
return;
}
if (!versionUpdateModel.isMustUpgrade() && !showDialogOnStart) {
cancel();
return;
}
if(checkCallBack != null){
checkCallBack.callBack(NEED_UPDATE);
}
final AlertDialog.Builder builer = ...//更新提醒對話框
builer.setPositiveButton("立刻更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
if (NetUtil.isWifi(context)) {
service.doDownLoadTask();
} else {
showNotWifiDownloadDialog();
}
}
});
//當點撤消按鈕時停止登錄
if (!versionUpdateModel.isMustUpgrade()) {
builer.setNegativeButton("稍後更新", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
cancel();
if(checkCallBack != null){
checkCallBack.callBack(USER_CANCELED);
}
}
});
}
builer.setCancelable(false);
waitForUpdateDialog = builer.create();
waitForUpdateDialog.show();
}
@Override
public void onError() {
unBindService();
...
}
});
service.setDownLoadListener(new VersionUpdateService.DownLoadListener() {
@Override
public void begain() {
VersionUpdateModel versionUpdateModel = service.getVersionUpdateModel();
if (versionUpdateModel.isMustUpgrade()) {
progressDialog = ...//生成進度條對話框
}
}
@Override
public void inProgress(float progress, long total) {
...//更新進度條
}
@Override
public void downLoadLatestSuccess(File file) {
...//履行勝利處置
unBindService();
}
@Override
public void downLoadLatestFailed() {
...//履行掉敗處置
unBindService();
}
});
service.doCheckUpdateTask();
}
...
}
最初,應用方法照樣異常簡略的。在BaseActivity中應用:
private VersionUpdateHelper versionUpdateHelper;
@Override
protected void onResume() {
super.onResume();
if(versionUpdateHelper == null)
versionUpdateHelper = new VersionUpdateHelper(this);
versionUpdateHelper.startUpdateVersion();
}
@Override
protected void onPause() {
super.onPause();
if(versionUpdateHelper != null)
versionUpdateHelper.stopUpdateVersion();
}
包管在每進入一個界面和分開界面時都將檢討更新(bindService)和撤消檢討(unBindService)。這時候有些同伙能夠以為如許做會不會糟蹋資本呢?沒有!
1,假如運用是強迫更新,那末在收集正常情形下進入運用就可以檢討出有新版本,這時候彈窗後用戶不克不及進入任何操作,沒無機會進入其余界面,一切沒有停止反復檢討;假如進入運用主頁因為收集成績,檢討掉敗,這時候固然不會彈窗提醒更新,然則假如用戶的收集恢復落後入任何其它界面都將獲得正常的版本更新檢討並彈窗提醒
2,假如運用長短強迫更新時,在Helper代碼裡停止了以下的斷定:
SettingActivity.java
private VersionUpdateHelper versionUpdateHelper;
@OnClick(R.id.rl_version_update)
public void onClickVersionUpdate(View view) {
if(updateTips.getVisibility() == View.VISIBLE){
return;
}
VersionUpdateHelper.resetCancelFlag();//重置cancel標志
if (versionUpdateHelper == null) {
versionUpdateHelper = new VersionUpdateHelper(this);
versionUpdateHelper.setShowDialogOnStart(true);
versionUpdateHelper.setCheckCallBack(new VersionUpdateHelper.CheckCallBack() {
@Override
public void callBack(int code) {
//EventBus發送新聞告訴紅點消逝
VersionUpdateEvent versionUpdateEvent = new VersionUpdateEvent();
versionUpdateEvent.setShowTips(false);
EventBus.getDefault().postSticky(versionUpdateEvent);
}
});
}
versionUpdateHelper.startUpdateVersion();
}
寫在最初
因為代碼較多,且多半代碼和ui相干,所以在文章中許多ui相干或許getter和setter辦法等非焦點代碼並沒有列出。演示代碼頂用了EventBus和OkHttp開源控件,詳細應用辦法望年夜家本身找相干材料進修。自己盤算有空的時刻寫個EventBus系列文章,望年夜家多多存眷。
文件下載也是應用的okHttp完成的,年夜家可以換成任何你熟習的下載框架。VersionUpdateService.java和VersionUpdateHelper.java的完全代碼可以到我的github高低載,因為時光關系並沒有相干用法的完全案例還瞥見諒,等有時光必定送上。