<1>簡介
Service和Handler是android重要的機制之一。
<2>關鍵步驟
服務一般分爲兩種:
1:本地服務, Local Service 用於應用程序內部。在Service可以調用Context.startService()啓動,調用Context.stopService()結束。在內部可以調用Service.stopSelf() 或Service.stopSelfResult()來自己停止。無論調用了多少次startService(),都只需調用一次stopService()來停止。
2:遠程服務, Remote Service 用於android系統內部的應用程序之間。可以定義接口並把接口暴露出來,以便其他應用進行操作。客戶端建立到服務對象的連接,並通過那個連接來調用服務。調用Context.bindService()方法建立連接,並啓動,以調用 Context.unbindService()關閉連接。多個客戶端可以綁定至同一個服務。如果服務此時還沒有加載,bindService()會先加載它。
提供給可被其他應用複用,比如定義一個天氣預報服務,提供與其他應用調用即可。
那麼先來看Service的生命週期吧:如圖:
context.startService()->onCreate()->onStart()->Service running--調用context.stopService()->onDestroy()
context.bindService()->onCreate()->onBind()->Service running--調用>onUnbind()-> onDestroy()從上可以知道分別對應本地的以及遠程的,也對應不同的方式啓動這個服務。
Handler 爲Android操作系統中的線程通信工具,包爲android.os.Handler。
與Handler綁定的有兩個隊列,一個爲消息隊列,另一個爲線程隊列。Handler可以通過這兩個隊列來分別:
發送、接受、處理消息–消息隊列;
啓動、結束、休眠線程–線程隊列;
Android OS中,一個進程被創建之後,主線程(可理解爲當前Activity)創建一個消息隊列,這個消息隊列維護所有頂層應用對象(Activities, Broadcast receivers等)以及主線程創建的窗口。你可以在主線程中創建新的線程,這些新的線程都通過Handler與主線程進行通信。通信通過新線程調用 Handler的post()方法和sendMessage()方法實現,分別對應功能:
post() 將一個線程加入線程隊列;
sendMessage() 發送一個消息對象到消息隊列;
當然,post()方法還有一些變體,比如postDelayed()、postAtTime()分別用來延遲發送、定時發送;
消息的處理,在主線程的Handler對象中進行;具體處理過程,需要在new Handler對象時使用匿名內部類重寫Handler的handleMessage(Message msg)方法;
從消息隊列中獲取消息。
線程加入線程隊列可以在主線程中也可以在子線程中進行,但都要通過主線程的Handler對象調用post()。
<3>出現的問題
不要忘記註冊service。
出現問題:
ActivityManager: Unable to start service Intent{ act=com.Android.MUSIC }: not found
解決方法:
1.檢查AndroidManifest.xml配置文件中是否配置了service
2.檢查service 是否在application標籤內
3.如果你的service和啓動的activity不在同一個包內,需要把service標籤中的android:name配置成service類的完全名(最好直接android:name配置成service類的完全名)。
<4>代碼及解釋
ServiceActivity.java:
package com.service;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
import com.test.R;
public class ServiceActivity extends Activity{
/**
* @ProjectName: [androidtest]
* @Package: [com.service.ServiceActivity.java]
* @ClassName: [ServiceActivity]
* @Description:
* @Author: [gmj]
* @CreateDate: [2013-9-8 上午9:33:34]
* @Version: [v1.0]
*/
ServiceConnection sc;
OnClickListener listener;
Handler hd = new Handler()
{
@Override
public void handleMessage(Message msg)
{
switch(msg.what)
{
case 0:
Toast.makeText(
ServiceActivity.this,
"調用Service的onCreate和onBind方法",
Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(
ServiceActivity.this,
"調用Service的onUnbind和onDistroy方法",
Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(
ServiceActivity.this,
"調用Service的onDistroy方法",
Toast.LENGTH_SHORT).show();
break;
case 3:
Toast.makeText(
ServiceActivity.this,
"調用Service的onCreate方法",
Toast.LENGTH_SHORT).show();
break;
}
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
sc=new ServiceConnection()
{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
listener=new OnClickListener()
{
@Override
public void onClick(View v) {
Intent intent=new Intent(ServiceActivity.this,myService.class);
switch(v.getId())
{
case R.id.serviceStart://Start Service
startService(intent);
hd.sendEmptyMessage(3);
break;
case R.id.serviceStop://Stop Service
stopService(intent);
hd.sendEmptyMessage(2);
break;
case R.id.serviceBind://Bind Service
bindService(intent,sc,BIND_AUTO_CREATE);
hd.sendEmptyMessage(0);
break;
case R.id.serviceUnBind://Unbind Service
unbindService(sc);
hd.sendEmptyMessage(1);
break;
}
}
};
this.findViewById(R.id.serviceStart).setOnClickListener(listener);
this.findViewById(R.id.serviceStop).setOnClickListener(listener);
this.findViewById(R.id.serviceBind).setOnClickListener(listener);
this.findViewById(R.id.serviceUnBind).setOnClickListener(listener);
}
}
myService.java:
package com.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class myService extends Service{
/**
* @ProjectName: [androidtest]
* @Package: [com.service.myService.java]
* @ClassName: [myService]
* @Description:
* @Author: [gmj]
* @CreateDate: [2013-9-8 上午9:29:22]
* @Version: [v1.0]
*/
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean onUnbind(Intent arg0)
{
Log.d("MyService", "=========onUnbind=========");
return super.onUnbind(arg0);
}
@Override
public void onRebind(Intent arg0)
{
super.onRebind(arg0);
Log.d("MyService", "=========onRebind=========");
}
@Override
public void onCreate()
{
super.onCreate();
Log.d("MyService", "=========onCreate=========");
}
@Override
public void onDestroy()
{
super.onDestroy();
Log.d("MyService", "=========onDestroy=========");
}
}