The function points for offline download are as follows:
1. Download management (start, cancel download).
2. Network Judgment (WI-FI,3G).
3. The independent process.
4. Timing and phone wake up.
5. Self-booting.
Choose the core method of offline downloadIt's easy to think of the service, but there are several issues (1) if the process and application of the service are consistent, the service restarts once after the app exits (2) if the service's process and application are inconsistent, Communication between processes can be a bit of a hassle (3) if the process and application of the service is consistent, select Intentservice, you can avoid restarting the problem and we do not need to download multiple tasks at the same time, with Intentservice can be fully, and Intentservice has other advantages
1. Download Management
Here is inconvenient to focus on the details of the download method, the network download a lot of ways, probably as follows:
1/** 2 * Download file 3 * @param URL 4 * @param dest Download stored local file 5 * @param append breakpoint Continuation 6 * @return 7 * @throws Exception 8 */9 public long download (String URL, File dest, Boolean append) throws exception{10 //Initial Variable one// preparation work// ... try {+ //... ( readsize = is.read (buffer)) > 0) { //network judgment os.write (buffer, 0, readsize); 20 Os.flush (); If you need to stop the download, such as Cancel, jump out of the current download }24 }25 } finally { ... }28 //... 29}
Here are a few things to note:
(1). When downloading, we want to be able to detect the network condition in time, for example, from Wi-Fi switching to 3G network, we should be able to stop the download in time.
(2). When the user chooses to cancel the download, we can also stop the current download.
2. Network Judgment
Get the current network status, mainly divided into Wi-Fi and mobile (including 3G,GPRS) Two, we write a tool class as follows:
1 public class Networkutils {2 3 public final static int NONE = 0;//No Network 4 public final static int WIFI = 1;// Wi-Fi 5 public final static int MOBILE = 2;//3g,gprs 6 7 /** 8 * Get current network status 9 * @param context10 * @ Return11 */12 public static int getnetworkstate (context context) { Connectivitymanager Connmanager = (Connectivitymanager) Context.getsystemservice (context.connectivity_service); //mobile network judgment state state = Connmanager.getnetworkinfo (connectivitymanager.type_mobile). GetState (); state.connected| | state = = state.connecting) { return mobile;19 }20 //wifi network judgment Connmanager.getnetworkinfo (Connectivitymanager.type_wifi). GetState (); if (state = = State.connected| | state = = state.connecting) { wifi;25 }26 return none;27 }28}
Depending on the status of the network, we are able to control how it is downloaded:
(1). The download volume is very large, we are unlikely to download in 3G, it is easy to arouse the user's dislike and concern.
(2). When the customer is very sure that it can be downloaded in 3G, it is also allowed.
So, here is a requirement, we want to set a flexible level for the download mode, combined with the characteristics of offline download, we give 3 of the program is selected by the user:
(1). Automatic download in case of mobile data
(2). Only allow Wi-Fi in the case of automatic download
(3). Close the Download
Here only the automatic download, is because if it is not automatic download, manual download user can be arbitrary control, without setting, of course, design to the loss of traffic conditions, such as 3G under manual download, prompting the user will consume a large amount of data traffic, with caution.
1 public class Constant {2 //Offline download network settings 3 public final static int offline_mobile = 0; 4 public final static int Offline_wifi = 1; 5 public final static int offline_off = 3; 6} 7 8 public class Global {9 //Set Default off state, ten //For application next startup can remember The first time the application is launched, this value should eventually be stored in the database, one public static int offlinenetworksetting = constant.offline_off;12}
It is now possible to compare the current network and offline network settings according to the rules to determine the open offline download service.
3. Independent processes
Offline download, whenever and wherever, as long as it is appropriate to carry out, the current mainstream approach is to set up back-office services.
1 public class Offlineserivice extends Service {2 //... 3}
(1). Offlineservice Process if the default and application-consistent, when the application process kill, will be restarted once (NetEase news in offline download, exit the application, download will pause for a little while this is the reason), if the impact is not small, this program is optional.
(2). Offlineservice processes and applications are separated, such as the application process is "Cn.cnblogs.tianxia.download", the process for offline download service is set to " Cn.cnblogs.tianxia.download.offline ", the relationship between the process of skimming and the application. Of course, this will bring a new problem, inter-process communication, of course, because the offline download and the module between the application independent, this problem is relatively good evasion.
(3). Offlineservice Process if the default and application-consistent, but Offlineservice inherited Intentservice, can avoid restarting the problem, this is the "Pro Android 3" book mentioned in the method, very good, but very sorry, I have only recently seen that I do not have a personal test at the moment and I dare not try it at work.
Scenario 3 is arguably the best option, but for personal reasons, option 2 is selected.
1 <manifest xmlns:android= "http://schemas.android.com/apk/res/android" 2 package= "Com.cnblogs.download" >3 <application android:icon= "@drawable/icon" android:label= "@string/app_name" > 4 5 <service android:name= "Cn.cnblogs.download.OfflineService" android:process= "Cn.cnblogs.download.offline"/> 6 </application>7 </manifest>
4. Timed Downloads and phone reminders
According to user settings, in the case of WiFi automatic download, but automatic download of the scheme there are many kinds of, frequent updates download, fixed-point download (8 in the morning, 4 o'clock in the afternoon), Interval download (every 6 hours).
Here, we choose to download it every 6 hours.
(1). Here is an error scenario. Once seen every 6 hours, it is easy to think of opening a child thread timing, accumulated to 6 hours, the child thread notifies the download service to start a new round of downloads. The idea of this program is not wrong, but ignore the phone is dormant, the child thread is actually stopped execution, so the so-called 6 hours of effect may never reach, and must be incorrect or inaccurate.
(2). Therefore, it is necessary to use a non-dormant approach: Timers and broadcast receivers. Every 6 hours we send a broadcast, broadcast receiver notification to start offline download. (Refer to Newsrob source code and book "Pro Android 3"):
1 public class Offlineserivice extends Service {2 3 //Last successful download time 4 private long lastdownloadtime; 5 //Omit generation Code...... 6 7 public static void Startalarm (context context) {8 Alarmmanager Alarmmanager = (Alarmmanager) Context.getsystemservice ("alarm"); 9 //Every 6 hours to send the broadcast to OFFLINEALARMRECEIVER11 //can also be set to 10 minutes to detect the download conditions, and in the offlinealarmrecrive to start the download, Avoid a 6-hour download failure and wait 6 hours for a long time. Intent Intent = new Intent (context,offlinealarmreceiver.class); pendingintent pendingintent = Pendingintent.getbroadcast (Context.getapplicationcontext (), 0, intent, 0); 15 Alarmmanager.cancel (pendingintent); alarmmanager.setrepeating (Alarmmanager.rtc_wakeup, System.currenttimemillis (), 3600000*6, pendingintent); }18}
Start download condition in Offlinealarmrecriver, and notify start download
1 public class Offlinealarmreceiver extends Broadcastreceiver {2 @Override 3 public void OnReceive (Context conte XT, Intent arg1) {4 5 //Omit code ..., initialize variable, prepare work ... 6 7 if (System.currenttimemillis ()-offlineservice.lastdownloadtime>3600000*60&& other conditions) {8 / /Open Offline download service 9 Intent alarmintent = new Intent (context, Offlineservice.class), Context.startservice ( alarmintent); }12 }13 14}
Earlier we mentioned the problem of thread hibernation, need to be able to wake up the phone when downloading, the download will be able to go back to hibernation, the following are two tool methods:
1 public static Powermanager.wakelock WakeLock; 2 /** 3 * Wake-up Service 4 */5 public static void Acquirewakel Ock (Context context) {6 7 if (wakelock!=null) {8 return; 9 }10 powermanager PowerManager = ( PowerManager) (Context.getsystemservice (Context.power_service)); WakeLock = Powermanager.newwakelock ( Powermanager.partial_wake_lock, "Com.cnblogs.download.OfflineService"); Wakelock.acquire (); }14 /**16 * Release wake-up service, return to sleep state */18 public static void Releasewakelock () { if (wakeLock !=null&&wakelock.isheld ()) { wakelock.release (); wakeLock = null;22 }23 }
Where powermanager.partial_wake_lock means to wake up the CPU only, at this time can automatically detect the network status, so as to ensure that the network is normal.
You need to set permissions in Mainifest.xml:
<uses-permission android:name= "Android.permission.WAKE_LOCK"/>
The wake-up status is then activated in the download service's Onstartconmmand () and then released after the download is complete:
1 @Override2 public int Onstartcommand (Intent Intent, int flags, int startid) {3 Acquirewakelock ( Offlineservice.this); 4 //Omit code ... 5 return Super.onstartcommand (Intent, flags, Startid); 6 }
5. Self-priming
For the sake of clarity, we define a self-booting receiver:
1/** 2 * self-initiated offline download service 3 * @author User 4 */5 public class Offlinereceiver extends Broadcastreceiver {6 @Ov Erride 7 public void OnReceive (context context, Intent arg1) {8 //Start Timer 9 offlineservice.startalarm ( (context) ,}11}12 Register this receiver in Androidmanifest.xml as follows: <receiver android:name= " Cn.cnblogs.download.OfflineReceiver ">15 <intent-filter>16 <!--self-starting-->17 <action Android:name= "Android.intent.action.BOOT_COMPLETED"/> <category android:name= " Android.intent.category.HOME "/> </intent-filter>20 </receiver>
This allows you to accept the start of the broadcast and perform a start timer operation at startup.
6. Summary
In order to be concise and clear, this article is only for offline download the most important point of association to enumerate, and for the cleanup Strategy, manual and automatic mode, interface jump, UI design and business requirements are not too much involved, but often these things is to spend a lot of your time, need a lot of details of the accumulation and patient debugging, The only thing we have to do is keep improving!
Learn about offline downloads for Android