这两个类是一个非常有意思的类,最开始接触的是在看高人关于省电的文章发现的.它可以让开发者在规定的时间内,然后在满足指定的条件下才开始执行任务.这样就牛逼多了.
但是这两个类只在Android5.0版本开始.用android studio平台来做开发.
<1> : 新建android工程:
<2> : 程序如下:
DurianMainActivity.java
package com.jobschedule.durian.durianschedule; import android.app.Activity; import android.app.job.JobInfo; import android.app.job.JobScheduler; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.TextView; public class DurianMainActivity extends Activity { private static final String TAG="DurianMainActivity"; TextView mWakeLockMsg; Button mButton; ComponentName mServieComponent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.durian_main); mWakeLockMsg=(TextView)findViewById(R.id.text); mServieComponent=new ComponentName(this,MyJobService.class); Intent startServiceIntent=new Intent(this,MyJobService.class); startService(startServiceIntent); mButton=(Button)findViewById(R.id.button); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pollServer(); } }); } public void pollServer(){ JobScheduler scheduler=(JobScheduler)this.getSystemService(Context.JOB_SCHEDULER_SERVICE); for(int i=0;i<10;i++){ JobInfo jobInfo=new JobInfo.Builder(i,mServieComponent) /* * 这会使你的工作不启动直到规定的毫秒数已经过去了 * */ .setMinimumLatency(5000) /* * 这将设置你的工作期限。即使是无法满足其他要求,你的任务将约在规定的时间已经过去时开始执行 * */ .setOverrideDeadline(60000) /* * 只有在设备处于一种特定的网络中时,它才启动 * 默认值是JobInfo.NETWORK_TYPE_NONE :无论是否有网络连接,该任务均可以运行 * JobInfo.NETWORK_TYPE_ANY,这需要某种类型的网络连接可用,工作才可以运行 * JobInfo.NETWORK_TYPE_UNMETERED,这就要求设备在非蜂窝网络中 * */ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build(); mWakeLockMsg.append("schedule job "+i+" !\n"); scheduler.schedule(jobInfo); } } }
MyJobService.java
package com.jobschedule.durian.durianschedule; import android.app.Service; import android.app.job.JobParameters; import android.content.Context; import android.content.Intent; import android.app.job.JobService; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; import java.io.IOError; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; public class MyJobService extends JobService { private final static String TAG="MyJobService"; @Override public void onCreate() { super.onCreate(); } @Override public boolean onStartJob(JobParameters params) { if(isNetworkConnected()){ new WebDownLoadTask().execute(params); return true; } return false; } @Override public boolean onStopJob(JobParameters params) { return false; } private boolean isNetworkConnected(){ ConnectivityManager connManager=(ConnectivityManager)this.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo=connManager.getActiveNetworkInfo(); return (networkInfo!=null && networkInfo.isConnected()); } private class WebDownLoadTask extends AsyncTask<JobParameters,Void,String>{ protected JobParameters mJobParam; @Override protected String doInBackground(JobParameters... params) { mJobParam=params[0]; try{ InputStream is=null; int len=50; URL url=new URL("https://www.baidu.com"); HttpURLConnection conn=(HttpURLConnection)url.openConnection(); conn.setReadTimeout(10000); conn.setConnectTimeout(15000); conn.setRequestMethod("GET"); conn.connect(); int response=conn.getResponseCode(); is=conn.getInputStream(); Reader reader=null; reader=new InputStreamReader(is,"UTF-8"); char[] buffer=new char[len]; reader.read(buffer); return new String(buffer); }catch (IOException e){ } return ""; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); jobFinished(mJobParam,false); } } @Override public void onDestroy() { super.onDestroy(); } }
主配置文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jobschedule.durian.durianschedule" > <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".DurianMainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyJobService" android:enabled="true" android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE"/> </application> </manifest>
其中:
android:permission="android.permission.BIND_JOB_SERVICE"
这一个配置非常重要,不然一直会包权限问题.
布局文件main_layout.xml很简单:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".DurianMainActivity"> <TextView android:text="@string/hello_world" android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" android:id="@+id/button"/> </LinearLayout>
运行之前建议先将设备连接到网络.
运行程序后,通过for循环将work全部先加入计划表中,然后服务更具时间限制,再对要求的条件进行判断,如果在限定的时间内,条件也会满足,服务就会想百度发送异步请求.
这种工作处理方式可以很大程度上改善APP的性能,不需要APP一直在后台运行"死守",这里面只需要规定时间内条件满足以后才会触发程序执行.相比定时器Timer,这个更加人性化,对性能优化更加充分.
详细可以参考:http://wiki.jikexueyuan.com/project/android-weekly/issue-146/using-jobscheduler.html,这里更加详细.