Android中Service的意義及用法
1、下面介紹Service和AsyncTask的用法和比較。
Service沒有介面,用於執行一個需要在後臺長期執行的任務。AsyncTask用於執行短時間的非同步任務,並跟UI執行緒互動,用於替代Thread和Handler。
1) MainActivity.java
2) activity_main.xmlpublic class MainActivity extends Activity { private static final String TAG = MainActivity.class.getSimpleName(); /**便於多次、多地呼叫,生命週期伴隨Activity*/ Intent intent; @Override protected void onCreate(Bundle savedInstanceState) { Log.i(TAG, "onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // mAsyncTask.execute("http://www.qinuli.com:83/picture/thumb.jpg", "http://www.qinuli.com:83/picture/hand_in_hand.jpg"); intent = new Intent(this, MyService.class); } protected void onDestroy() { Log.d(TAG, "onDestroy"); super.onDestroy(); }; /** * 定義一個AsyncTask的子類;例項化並在UI執行緒呼叫其execute方法 * <li>3個引數:Params、Progress、Result * <li>4 steps:onPreExecute->doInBackground->onProgressUpdate->onPostExecute * <li>功能:用於後臺執行前臺顯示的任務 * <li>意義:代替或封裝Thread和Handler,方便後臺執行緒和UI執行緒互動 */ AsyncTask<String, Integer, CharSequence> mAsyncTask = new AsyncTask<String, Integer, CharSequence>() { @Override protected void onPreExecute() { Log.d(TAG, "onPreExecute"); }; @Override protected CharSequence doInBackground(String... params) { //perform a computation on a background thread for(int i=0;i<params.length;i++){ publishProgress(Integer.valueOf(i)); } return "加油!"; } @Override protected void onProgressUpdate(Integer... values) { Log.d(TAG, "onProgressUpdate-"+values[0]); }; @Override protected void onPostExecute(CharSequence result) { Log.d(TAG, "onPostExecute-"+result); }; }; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { Log.d(TAG, "onServiceDisconnected-"+name.getClassName()); } @Override public void onServiceConnected(ComponentName name, IBinder service) { //由bindService觸發,在onBind之後 MyService myService = ((MyBinder)service).getService(); Log.d(TAG, "onServiceConnected-"+name.getClassName()+"-"+myService.name); } }; public void onClick(View v){ switch (v.getId()) { case R.id.btn_startService: //呼叫Service的空參構造 startService(intent); break; case R.id.btn_stopService: stopService(intent); break; case R.id.btn_bindService: bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); break; case R.id.btn_unbindService: unbindService(mServiceConnection); } } }
3) MyService.java,講解startService和bindService的原理<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"> <Button android:id="@+id/btn_startService" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="onClick" android:text="startService"/> <Button android:id="@+id/btn_stopService" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="onClick" android:text="stopService"/> <Button android:id="@+id/btn_bindService" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="onClick" android:text="bindService"/> <Button android:id="@+id/btn_unbindService" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="onClick" android:text="unbindService"/> </LinearLayout>
4) MyIntentService.java,IntentService用於在後臺執行緒執行非同步任務,執行完Service自動destroy/** * <li>Service的意義:perform a longer running operation * <li>Service和AsyncTask的區別:Service執行在主執行緒,不會結束 */ public class MyService extends Service { private static final String TAG = MyService.class.getSimpleName(); private MyBinder myBinder = new MyBinder(); public String name = "ShiXin"; public MyService(){ super(); Log.d(TAG, "MyService"); } /**繼承Binder類,Binder類實現IBinder介面。例項化該類供onBind使用*/ public class MyBinder extends Binder{ /**返回Service的例項,進而呼叫其方法和屬性,實現一些資料通訊和功能操作*/ public MyService getService(){ return MyService.this; } } @Override public IBinder onBind(Intent intent) { Log.d(TAG, "onBind"); //由bindService觸發 return myBinder; } @Override public boolean onUnbind(Intent intent) { Log.d(TAG, "onUnbind"); return super.onUnbind(intent); } @Override public void onCreate() { Log.d(TAG, "onCreate"); //重新例項化新的Service super.onCreate(); } public void onDestroy() { Log.d(TAG, "onDestroy"); super.onDestroy(); }; @Override public void onStart(Intent intent, int startId) { //deprecated 被onStartCommand代替 super.onStart(intent, startId); } @Override public int onStartCommand(Intent intent, int flags, int startId) { //每次startService都會觸發,bindService不會觸發 //startId:unique integer token,標記每次startService,Service建立後從1開始計數 //START_STICKY_COMPATIBILITY 0;Service.START_STICKY 1 stopSelfResult(3);//onStartCommand執行3次 int state = super.onStartCommand(intent, flags, startId); Log.d(TAG, "onStartCommand-"+intent.getComponent().getClassName()+"-"+flags+"-"+startId+"-"+state); return state;//1 } }
/**
* handle asynchronous requests
*/
public class MyIntentService extends IntentService {
private static final String TAG = MyIntentService.class.getSimpleName();
public MyIntentService() {
//name worker thread
super("worker thread");
}
@Override
protected void onHandleIntent(Intent intent) {
//代替onStartCommand;執行完呼叫stopSelf()
Log.d(TAG, Thread.currentThread().getName()+"-onHandleIntent");
}
@Override
public void onCreate() {
Log.d(TAG, "onCreate");
super.onCreate();
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
}
5) AndroidManifest.xml<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.qinuli.testproject"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity android:name="com.qinuli.testproject.MainActivity">
<intent-filter >
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name="com.qinuli.testproject.MyService"></service>
<service android:name="com.qinuli.testproject.MyIntentService"></service>
</application>
</manifest>
2、如何讓服務永久執行
本示例介紹了TIME_TICK和BOOT_COMPLETED廣播的用法
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
public void onClick(View v){
switch(v.getId()){
case R.id.btn_killProcess:
Process.killProcess(Process.myPid());
}
}
}
MyService.java
public class MyService extends Service {
private static final String TAG = MyService.class.getSimpleName();
private MyBinder myBinder = new MyBinder();
public class MyBinder extends Binder{
public MyService getService(){
return MyService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
@Override
public void onCreate() {
Log.d(TAG, "onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
//程序被殺死,服務會重建
return Service.START_STICKY;
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
}
MyApplication.javapublic class MyApplication extends Application {
private static final String TAG = MyApplication.class.getSimpleName();
MyService myService;
Intent intent;
@Override
public void onCreate() {
Log.d(TAG, "onCreate");
super.onCreate();
intent = new Intent(this, MyService.class);
startService(intent);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
registerReceiver(new TimeTickReceiver(), new IntentFilter(Intent.ACTION_TIME_TICK));
}
@Override
public void onTerminate() {
Log.d(TAG, "onTerminate");
super.onTerminate();
stopService(intent);
//禁用一個manifest receiver,可禁用清單檔案裡註冊的四大元件
ComponentName componentName = new ComponentName(this, BootCompletedReceiver.class);
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
myService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected");
myService = ((MyBinder)service).getService();
}
};
}
BootCompleteReceiver.javapublic class BootCompletedReceiver extends BroadcastReceiver {
private static final String TAG = BootCompletedReceiver.class.getSimpleName();
public BootCompletedReceiver(){
super();
Log.d(TAG, "BootCompletedReceiver");
}
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, action);
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
//清單檔案註冊,開機可收到廣播
boolean isServiceRunning = false;
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for(RunningServiceInfo runningServiceInfo:activityManager.getRunningServices(Integer.MAX_VALUE)){
if(MyService.class.getName().equals(runningServiceInfo.service.getClassName())){
isServiceRunning = true;
}
}
if(!isServiceRunning){
ComponentName comp = new ComponentName(context.getPackageName(), MyService.class.getName());
context.startService(new Intent().setComponent(comp));
}
}else if(ConnectivityManager.CONNECTIVITY_ACTION.equals(action)){
//在清單檔案註冊,退出APP或殺死程序依然能收到廣播,但清掉記憶體就收不到了
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if(networkInfo!=null)
Log.d(TAG, "networkstate:"+networkInfo.isConnectedOrConnecting()+"-"+(networkInfo.getType()==ConnectivityManager.TYPE_MOBILE));
}
}
}
TimeTickReceiver.javapublic class TimeTickReceiver extends BroadcastReceiver {
private static final String TAG = TimeTickReceiver.class.getSimpleName();
public TimeTickReceiver(){
super();
Log.d(TAG, "TimeTickReceiver");
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, action);
if (Intent.ACTION_TIME_TICK.equals(action)) {
boolean isServiceRunning = false;
//拿到所有正在執行的服務
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for(RunningServiceInfo runningServiceInfo:activityManager.getRunningServices(Integer.MAX_VALUE)){
if(MyService.class.getName().equals(runningServiceInfo.service.getClassName())){
isServiceRunning = true;
}
}
Log.d(TAG, "isServiceRunning="+isServiceRunning);
if(!isServiceRunning){
ComponentName comp = new ComponentName(context.getPackageName(), MyService.class.getName());
context.startService(new Intent().setComponent(comp));
}
}
}
}
AndroidManifest.xml<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.qinuli.servicetest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:name="com.qinuli.servicetest.MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity android:name="com.qinuli.servicetest.MainActivity">
<intent-filter >
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name="com.qinuli.servicetest.MyService"
android:enabled="true"
android:exported="false"/>
<receiver
android:name="com.qinuli.servicetest.BootCompletedReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
</application>
</manifest>
相關推薦
static修飾符 (在類中的意義及用法)
(以下內容參考C++static的用法總結 這裡講的不會很詳細,主要是幾點: static的意義 為什麼要用static修飾符? 大家都知道,函式內部定義的變數在函式結束時就會釋放掉,然而要想
Android中Service的意義及用法
1、下面介紹Service和AsyncTask的用法和比較。 Service沒有介面,用於執行一個需要在後臺長期執行的任務。AsyncTask用於執行短時間的非同步任務,並跟UI執行緒互動,用於替代Thread和Handler。 1) MainActivity.java
python中\r的意義及用法
\r的意義 \r 表示將游標的位置回退到本行的開頭位置 \b表示將游標的位置回退一位 在python裡print會預設進行換行,可以通過修改引數讓其不換行 (1) python2中可以在print語句的末尾加上逗號,程式碼如下: print "
Android 中Service 和Activity之間傳值。(涉及BroadCast的基本用法)
首先先建立一個Android工程(名字自定義)這裡我命名為MyActivity 包名為:package org.hm.myactivity; 再最後給自己的activity命名(名字自定義)此處我命名為MyTestActivity public class MyTestA
Android中Calendar類的用法總結
jsb ews 寫法 需要 key data- minute bar 來講 Calendar是Android開發中需要獲取時間時必不可少的一個工具類,通過這個類可以獲得的時間信息還是很豐富的,下面做一個總結,以後使用的時候就不用總是去翻書或者查資料了。 在獲取時間之前要先獲
(轉)Android中Parcelable接口用法
string date 場景 應用 用法 反序列化 數組 auth 序列化對象 1. Parcelable接口 Interface for classes whose instances can be written to and restored from a Parce
Android中Service和IntentService的差別
前言: ServiceTimeout(20 seconds)小概率型別Service在特定的時間內無法處理完成,會造成ANR — 應用程式無響應(ANR:Application Not Responding)的情況 ▲ 分析 : 避免ANR最核心的一點就是在主執行緒減少耗時操作。這時我們
Android中Service的使用方法
目錄 Service 介紹 Service兩種啟動方式 使用 測試 IntentService Activity與Service之間的通訊 繼承Binder類 Messenger AIDL Service 介紹
Android 常用 mimeType 表及用法
常用mimeType表: 檔案型別 mime名稱
Android中Service的工作過程
我們知道,Service有兩種工作狀態,一種是啟動狀態,主要用於執行後臺計算; 另一種是繫結狀態,主要用於和其它元件的互動。而且這兩種狀態是可以共存的,關於Service的使用可以看之前的文章《Android裡服務Service的使用》。今天主要是對Service的啟動狀態和
EOF的意義及用法(while(scanf("%d",&n) != EOF))
EOF,為End Of File的縮寫,通常在文字的最後存在此字元表示資料結束。 在微軟的DOS和Windows中,讀取資料時終端不會產生EOF。此時,應用程式知道資料來源是一個終端(或者其它“字元裝置”),並將一個已知的保留的字元或序列解釋為檔案結束的指明;最
Android中AsyncTask的簡單用法
在開發Android移動客戶端的時候往往要使用多執行緒來進行操作,我們通常會將耗時的操作放在單獨的執行緒執行,避免其佔用主執行緒而給使用者帶來不好的使用者體驗。但是在子執行緒中無法去操作主執行緒(UI 執行緒),在子執行緒中操作UI執行緒會出現錯誤。因此android提供
android 中layer-list的用法
1.可以將多個圖片按照順序層疊起來 2.在drawable下建立一個xml檔案 [xhtml:showcolumns] view plaincopyprint? <?xml version="1.0" encoding="UTF-8"?>
Android中的Selector的用法
Android中的Selector主要是用來改變ListView和Button控制元件的預設背景。其使用方法可以按一下步驟來設計: (以在mylist_view.xml為例) 1.建立mylist_view.xml檔案 首先在res目錄下新建drawable資料夾,再在
Android控制元件介紹及用法
第一部分 個性化控制元件(View) 主要介紹那些不錯個性化的View,包括ListView、ActionBar、Menu、ViewPager、Gallery、GridView、ImageView、ProgressBar及其他如Dialog、Toast、EditText、TableView、Activi
Android 中string-array的用法
本人小菜一枚,第一次寫部落格,從網上查到的一些知識點自己總結吧。總覺得部落格是一個很多好的記錄知識點的地方,歡迎指正,謝謝。 1、使用string-array的原因 在實際開發中,當資
Android中Service與Activity資料互動的簡單理解
Service跟Activity是最相似的元件,都代表可執行的程式,區別在於:Service一直在後臺執行,沒有跟使用者互動的介面。 啟動與停止Service有兩種方法: 第一種通過startService()與stopService()啟動和停止服務,Se
Android中Service(服務)詳解
Service是Android中四大元件之一,在Android開發中起到非常重要的作用,先來看一下官方對Service的定義: A is an application component that can perform long-running operation
Android中Service的使用詳解和注意點(LocalService)
開始,先稍稍講一點android中Service的概念和用途吧~ Service分為本地服務(LocalService)和遠端服務(RemoteService): 1、本地服務依附在主程序上而不是獨立的程序,這樣在一定程度上節約了資源,另外Local服務因為是在同一程序因此
Android中Service使用bindService
前面已經對Service的startServer方式啟動一個服務瞭解過了,現在來看一下Service的另一種啟動方式→bindServer bindServer使用場景 1、在同個app之間呼叫(即是同一個程序中) 2、在不同app之間呼叫(即是跨程序間通訊) 同個app