The requirement for a version to be checked and updated in development is basically the functionality that all applications must have, but some friends in actual development tend to overlook some details.
Basic process of version update:
Typically, the local version is told to the server, the server through the relevant processing will return the client-related information, tell the client need not update, if you need to update is mandatory or not mandatory update. The client gets the relevant information returned by the server and makes further logical processing.
Force Update:
The general processing is to enter the application of the window to notify users have version update, the window can not cancel the button and cannot be canceled. The user can only choose to update or turn off the application, and of course, add the Cancel button, but if the user chooses to cancel, it will exit the application directly.
Non-mandatory update
The general process is to add a version check to the application settings, and if the user actively checks the version, the window tells the user that there is a version update. The user can then cancel or update.
function is actually relatively simple and clear, but the reason to write this article, because in one of our company's project, I gave this module to a 4 years of work experience of the brother to write, finally this man spent 2 hours to finish. I also think this guy writes very quickly, the efficiency is very high, the result one test found many problems:
1. Before entering the front page to close the network, enters after the refresh interface to discover the forced update reminder does not have the window
2. Access to other interfaces without any update reminders
3. Click OK update in normal update, do not Judge network state (WiFi, mobile network) directly download APK file, if the user will consume very much traffic under the mobile network, directly affect the user experience
4. Download process in the application of no progress bar reminders, notice bar also no progress reminders
5. apk file download process, if forced to end the application, the download was interrupted
6. apk if the normal download, pop up the installation interface, then if the user canceled the installation back to the application, in need of mandatory update in case there is no more pop-up window to prevent users from doing any other operation, lost the significance of mandatory update
First of all, I do not have the slightest meaning yo, just want to say that as a qualified programmer, we need to do the least rigorous thinking of this, in the case of ability to the user experience to suggest the best. Write your own code must undergo rigorous testing and delivery, do not expect testers to help you test and then modify, you know that many companies are not professional testers and even no test personnel yo.
The reasons for the above problems are analyzed and the solutions are as follows:
For 1, 2 questions
It's clear that he wrote the update work on the home page of the application (such as mainactivity) and did not check for updates on any other interface.
Solution
Every interface needs to check for updates, and of course we can't copy and paste the same code in every activity. It is valuable to define a baseactivity and all other activity inherits from it. You can put an action to check for updates in baseactivity related methods, such as in Onresume, so that every time you display an interface, you will perform an action to check for updates.
For 5 problems, if the download is done in the activity, if the application terminates unexpectedly or forces the application to quit, the download thread will also be terminated
Solution
The download task can be performed in a service so that even the application of the terminated service has a guaranteed mechanism (Startforeground) that gives the service a great opportunity to continue executing
For 6 problems, if checking for updates is not performed again at the resume of the activity, then it is natural to return to the event without checking for updates and bouncing windows.
Solution
continue to check for updates in the onresume of the activity, if forced update the window prevents users from doing anything else
For 3, 4 questions, I think it's not a procedural problem, but an attitude problem, actually adding non-WiFi and progress display is very simple
Overall Solution
Define service classes, such as Versionupdateservice.java. Mainly provide version check and file download operation
Define the Versionupdatehelper class to use the service and provide interaction with the foreground activity
If you have a problem with the use of service (need to update the front UI frequently, etc.), we suggest that you read the Android image compression upload series-service This article first to understand.
The core code is as follows:
public class Versionupdateservice extends Service {private Localbinder binder = new Localbinder ();
Private downloadlistener downloadlistener;//Download Task Listener callback interface 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;//Check result listener callback Interface 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) {n Otificationbuilder.setcontenttitle ("Downloading Update" + Progress + "%");
The label of the entry Notificationbuilder.setprogress (MB, progress, false);
...
}
} private void Stardownloadforground () {//create notification bar Notificationbuilder = new Notification.builder (this);
...
Notification Notification = Notificationbuilder.getnotification ();
Startforeground (notification_id, NOTIFICATION);
private void Stopdownloadforground () {Stopforeground (true);
///Perform version check task public void Docheckupdatetask () {//Get this fixed version number final int currentbuild = Apputil.getversioncode (this); Call Version Check interface Apimanager.getinstance (). Versionapi.upgraderecords (Currentbuild, New Requestcallback () {@Override Publ IC void onsuccess (Headers Headers, String response) {Versionupdatemodel = Json.parseobject (response, Versionupdatemo
Del.class);
... if (checkversioncallback!= null) checkversioncallback.onsuccess ();
@Override public void OnError (int code, String response) {...}
});
public void Dodownloadtask () {stardownloadforground (); StartNotification bar Progress Update thread notificationupdaterthread = new Notificationupdaterthread ();
Notificationupdaterthread.start ();
File download store path 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) {...//Execution Progress Update if (Downloadlistener!= null) downloadlistener.i
Nprogress (Progress_, total); @Override public void onsuccess (Headers Headers, String response) {//Execute successful callback ... installapk (DestFile,
Versionupdateservice.this);
@Override public void OnError (int code, String response) {...//execute failed callback}});
}//install apk public void installapk (file file, 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 {this.context = context;
public void Startupdateversion () {if (iscanceled) return;
if (iswaitforupdate () | | | iswaitfordownload ()) {return; } if (service = = NULL && context!= null) {Context.bindservice (new Intent, Versionupdateservice.clas
s), 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 (conte
XT);
Builer.settitle ("Download new version");
Builer.setmessage ("Check to see that your network is not WiFi, download the new version will consume a certain amount of traffic, continue downloading?"); Builer.setnegativebutton ("later"), new Dialoginterface.onclicklistener () {@Override public void OnClick (Dialoginterfa
Ce dialog, int which) {...//if it is forced to update the exit app if (mustupdate) {mainapplication.getinstance (). Exitapp ();
}
}
}); Builer.setpositivebutton ("Continue downloading", new Dialoginterface.onclicklistener () {@Override public void OnClick (Dialoginterfa
Ce dialog, int which) {dialog.cancel ();
Service.dodownloadtask ();
}
});
...
} @Override Public VOID onserviceconnected (componentname name, IBinder binder) {service = ((Versionupdateservice.localbinder) binder). GetS
Ervice (); Service.setcheckversioncallback (New Versionupdateservice.checkversioncallback () {@Override public void onsuccess ()
{Versionupdatemodel Versionupdatemodel = Service.getversionupdatemodel ();
Eventbus control update Red dot hint 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 = ...//Update prompt dialog box Builer.setpositivebutton ("Update Now", New dialoginterface.onclicklist Ener () {@Override public void OnClick (Dialoginterface dialog, int which) {dialog.canceL ();
if (Netutil.iswifi (context)) {service.dodownloadtask ();
else {shownotwifidownloaddialog ();
}
}
}); Log on when the button is canceled if (!versionupdatemodel.ismustupgrade ()) {Builer.setnegativebutton ("Update Later", New Dialoginterface.onc
Licklistener () {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 () {Versi
Onupdatemodel Versionupdatemodel = Service.getversionupdatemodel (); if (Versionupdatemodel.ismustupgrade ()) {ProgressDialog = ...//Generate Progress Bar dialog box}} @OverrIDE public void InProgress (float progress, long total) {...//update progress bar} @Override public void downloadlates
Tsuccess (file file) {...//execution successful processing unbindservice ();
@Override public void downloadlatestfailed () {...//execute failure handling unbindservice ();
}
});
Service.docheckupdatetask ();
}
...
}
Finally, the use of the method is very simple. Used in 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 ();
}
Ensure that updates (Bindservice) and cancellation checks (Unbindservice) are checked every time you enter an interface and leave the interface. At this point some friends may think that this will not waste resources? No!
1, if the application is forced to update, then the network under normal conditions to enter the application can check out a new version, when the window after the user can not enter any operation, there is no chance to enter another interface, all did not carry out repeated inspection; If you enter the application homepage due to network problems, the check fails, while the window will not be updated, However, if the user's network recovers and enters any other interface, it will get a normal version update check and window tips
2, if the application is a mandatory update, the following judgment is made in the helper code:
Settingactivity.java
private Versionupdatehelper versionupdatehelper;
@OnClick (r.id.rl_version_update) public
void Onclickversionupdate (view view) {
if updatetips.getvisibility () = = view.visible) {return
;
}
Versionupdatehelper.resetcancelflag ()//Reset Cancel Mark
if (versionupdatehelper = = null) {
Versionupdatehelper = New Versionupdatehelper (this);
Versionupdatehelper.setshowdialogonstart (true);
Versionupdatehelper.setcheckcallback (New Versionupdatehelper.checkcallback () {
@Override public
Void CallBack (int code) {
//eventbus send message notification red dot disappears
versionupdateevent versionupdateevent = new Versionupdateevent () ;
Versionupdateevent.setshowtips (false);
Eventbus.getdefault (). Poststicky (Versionupdateevent);}}
);
Versionupdatehelper.startupdateversion ();
}
Written in the last
Because there is more code and most of the code is related to the UI, Non-core code, such as many UI-related or getter and setter methods, is not listed in the article. The demo code uses the Eventbus and okhttp Open source control, the concrete use method hope everybody looks for the relevant material to study. I intend to have time to write a Eventbus series of articles, I hope we pay more attention.
File downloads are also used by Okhttp implementations, and you can replace them with any familiar download framework. Versionupdateservice.java and Versionupdatehelper.java complete code can be downloaded to my GitHub, due to the time relationship is not related to the use of the complete case also hope to forgive, and so there will be time to serve.