編輯:關於Android編程
service作為android的四大組件之一,其重要性可想而知,在開發中,我們經常把一些不需要與用戶進行交互的工作放在service中來完成,service運行在後台,這樣有些人可能會產生錯覺,以為service是運行在新線程中,其實不然,service也運行在主線程中,因此不能在service中進行耗時操作,否則會報ANR異常,但是我們可以在service中新開線程來進行耗時操作,比如下載等等。
先來說說service的兩種綁定方式,一種是通過Context.startService()來啟動,另一種是綁定的方式,通過bindService方法來實現。
第一種啟動方式:我們一般在onStart()方法中啟動service(使用方法startService()或者bindService()),在onStop方法中停止service(使用方法stopService()或者unbindService())。
先來看看第一種:
public class MyService1 extends Service {
@Override
public void onCreate() {
Log.i(lenve, onCreate());
sendMsg2Activity(服務創建);
}
//廢棄的方法,不再使用
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i(lenve, onStart());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(lenve, onStartCommand());
return super.onStartCommand(intent, flags, startId);
}
private void sendMsg2Activity(String string) {
Intent intent = new Intent(service2activity);
intent.putExtra(msg, string);
this.sendBroadcast(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(lenve, onDestroy());
}
@Override
public IBinder onBind(Intent intent) {
Log.i(lenve, onBind());
return null;
}
}
在Activity中啟動Service
intent = new Intent(this, MyService1.class);
startService(intent);
停止service
stopService(intent);
通過打印日志我們可以發現,第一次調用service時會觸發onCreate()方法,後面的調用則不會再執行onCreate()方法,無論我們啟動了多少次Service,它都只有一個,即停止service只需執行一次即可。
第二種,通過綁定的方式啟動service
如果要細分的話這種啟動方式又分為兩種:
1.設計接口,通過Ibinder實現接口來對Activity暴露方法供其調用。
接口:
public interface MyServiceInterface {
public int add(int a,int b);
}
MyService.java
public class MyService1 extends Service {
private IBinder myBinder = new MyBinder();
public class MyBinder extends Binder implements MyServiceInterface{
@Override
public int add(int a, int b) {
return a+b;
}
}
@Override
public IBinder onBind(Intent intent) {
Log.i(lenve, onBind());
return myBinder;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(lenve, onCreate());
myBinder = new MyBinder();
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(lenve, onDestroy());
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(lenve, onUnbind());
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
Log.i(lenve, onRebind());
}
}
在activity中啟動service並調用add方法:
public class MainActivity extends Activity {
private TextView tv1;
private ServiceConnection conn;
private Intent intent;
private MyServiceInterface msi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) this.findViewById(R.id.textView1);
intent = new Intent(this, MyService1.class);
Log.i(lenve, + 1);
conn = new ServiceConnection() {
// 連接中斷時調用
@Override
public void onServiceDisconnected(ComponentName name) {
}
// 連接成功時調用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
msi = (MyServiceInterface) service;
Log.i(lenve, 連接成功!);
}
};
bindService(intent, conn, BIND_AUTO_CREATE);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
tv1.setText(msi.add(4, 5) + );
break;
default:
break;
}
}
@Override
protected void onStop() {
super.onStop();
unbindService(conn);
}
}
我們通過接口,可以在Activity中調用service中的方法,這樣便實現了兩者之間的通信。
2.在onBinder()中返回Binder,而在繼承Binder的類中直接返回當前service對象,通過該service對象來調用service中公開的方法。
service代碼
public class MyService2 extends Service {
private IBinder myBinder = new MyBinder();
public class MyBinder extends Binder {
public MyService2 getService() {
return MyService2.this;
}
}
@Override
public IBinder onBind(Intent intent) {
Log.i(lenve, onBind());
return myBinder;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(lenve, onCreate());
myBinder = new MyBinder();
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(lenve, onDestroy());
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(lenve, onUnbind());
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
Log.i(lenve, onRebind());
}
public int minus(int a, int b) {
return a - b;
}
}
activity中綁定:
public class MainActivity extends Activity {
private TextView tv1;
private ServiceConnection conn;
private Intent intent;
private MyService2 ms2;
private MyServiceInterface msi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) this.findViewById(R.id.textView1);
// intent = new Intent(this, MyService1.class);
intent = new Intent(this, MyService2.class);
conn = new ServiceConnection() {
// 連接中斷時調用
@Override
public void onServiceDisconnected(ComponentName name) {
}
// 連接成功時調用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// msi = (MyServiceInterface) service;
//拿到當前service對象
MyBinder mb = (MyBinder) service;
ms2 = mb.getService();
Log.i(lenve, 連接成功!);
}
};
bindService(intent, conn, BIND_AUTO_CREATE);
// new Thread(new Runnable() {
//
// @Override
// public void run() {
// try {
// Thread.sleep(2000);
// tv1.setText(msi.add(4, 5)+);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// }).start();
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
//直接調用service中的public方法
tv1.setText(ms2.minus(9, 6)+);
// tv1.setText(msi.add(4, 5) + );
break;
default:
break;
}
}
@Override
protected void onStop() {
super.onStop();
unbindService(conn);
}
}
個人覺得第二種方式更好,不僅省事,而且交互也比較方便。
其實,如果想實現service和activity之間的通信還可以使用broadcast。
更高深的aidl我們下回分解。
之前網上看了下自定義消息欄,通知欄,了解到了Notification這個控件,發現UC浏覽器等都是這種類型,今天寫個demo實現下,如圖:其中每個按鈕都有不同的功能,代碼
Android基礎入門教程——10.11 傳感器專題(2)——方向傳感器標簽(空格分隔): Android基礎入門教程本節
一、Android 提供了三種方式: android語音識別方法一:使用intent調用語音識別程序 1. 說明 以下例程功能為:在應用程序中使用inte
篇幅較長遂分成上下兩篇,上一篇我們已經快要一氣呵成了,但是美中不足的是,這個界面並不能討得美工MM的歡心,美工MM曾寄希望於您,卻交出這麼作出這麼一副死型樣,我都替你汗顏