編輯:關於Android編程
本節我們學習Android四大天王的Service,如果把Activity比作是前台程序,那麼Service就是後台程序,Service的整個生命周期只會在後台執行。它一般沒有用戶操作界面,運行於系統中不容易被用戶發覺,可以用來開發如監控之類的程序。與Activity一樣,Service也是通過Intent來調用。
一、創建Service
1.繼承API的Service類[java]
public class CustomService extends Service {...}
public class CustomService extends Service {...}2.在AndroidManifest.xml的<application>標簽中對創建的Service進行注冊
[html]
<service android:name=".MyService" />
<service android:name=".MyService" />二、啟動Service
服務不能自己運行,需要通過調用Context.startService()或Context.bindService()方法啟動服務。這兩個方法使用場合有所不同。
1.采用Context.startService()方法啟動服務
當服務未被創建時,系統會先調用服務的onCreate()方法,接著調用onStartCommand(...)方法。如果調用startService()方法前服務已經被創建,多次調用startService()方法並不會導致多次創建服務,但會導致多次調用onStartCommand(...)方法。采用startService()方法啟動的服務,只能調用stopService()方法結束服務,服務結束時會調用onDestroy()方法。采用這種方式啟用服務,調用者與服務之間沒有關聯,即使調用者退出了,服務仍然運行。
2.采用Context.bindService()方法啟動服務
當服務未被創建時,系統會先調用服務的onCreate()方法,接著調用onBind()方法。這個時候調用者和服務綁定在一起,調用者退出了,系統就會先調用服務的onUnbind()方法,接著調用onDestroy()方法。如果調用bindService()方法前服務已經被綁定,多次調用bindService()方法並不會導致多次創建服務及綁定(也就是說onCreate()和onBind()方法並不會被多次調用)。如果調用者希望與正在綁定的服務解除綁定,可以調用unbindService()方法,調用該方法也會導致系統調用服務的onUnbind()方法,接著調用onDestroy()方法。采用這種方式啟用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止。
三、Service生命周期
既然官方沒有為Service生命周期提供示意圖,那麼我們就模仿Activity生命周期示意圖繪制一張,然後再進行總結。
從上圖可以看出,其實Service的生命周期可以分為如下兩個場景:
1.由Context.startService()啟動生命周期:startService() ☞ onCreate() ☞ onStartCommand() ☞ stopService() ☞ onDestroy()
多次調用startService()方法盡管不會多次創建服務,但onStartCommand()方法會被多次調用。
2.由Context.bindService()啟動生命周期:bindService() ☞ onCreate() ☞ onBind() ☞ unbindService() ☞ onUnbind() ☞ onDestroy()
當調用者與服務已經綁定時,多次調用bindService()方法並不會導致onBind()方法被多次調用。
四、Service案例
1.案例代碼陳列
AndroidManifest.xml
[html]
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.lynn.service"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
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=".MyService" />
</application>
</manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.lynn.service"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
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=".MyService" />
</application>
</manifest>strings.xml
[html]
<resources>
<string name="app_name">Android四大天王之Service</string>
</resources>
<resources>
<string name="app_name">Android四大天王之Service</string>
</resources>main.xml[html] view plaincopyprint?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btnStartMyService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StartMyService" />
<Button
android:id="@+id/btnStopMyService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopMyService" />
<Button
android:id="@+id/btnBindMyService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BindMyService" />
<Button
android:id="@+id/btnUnbindMyService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="UnbindMyService" />
<Button
android:id="@+id/btnExitActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ExitActivity" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btnStartMyService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StartMyService" />
<Button
android:id="@+id/btnStopMyService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StopMyService" />
<Button
android:id="@+id/btnBindMyService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BindMyService" />
<Button
android:id="@+id/btnUnbindMyService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="UnbindMyService" />
<Button
android:id="@+id/btnExitActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ExitActivity" />
</LinearLayout>MainActivity.java
[java]
package cn.lynn.service;
import cn.lynn.service.R;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
Button mBtnStartMyService;
Button mBtnStopMyService;
Button mBtnBindMyService;
Button mBtnUnbindMyService;
Button mBtnExitActivity;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mBtnStartMyService = (Button) findViewById(R.id.btnStartMyService);
mBtnStartMyService.setOnClickListener(new MyOnClickListener());
mBtnStopMyService = (Button) findViewById(R.id.btnStopMyService);
mBtnStopMyService.setOnClickListener(new MyOnClickListener());
mBtnBindMyService = (Button) findViewById(R.id.btnBindMyService);
mBtnBindMyService.setOnClickListener(new MyOnClickListener());
mBtnUnbindMyService = (Button) findViewById(R.id.btnUnbindMyService);
mBtnUnbindMyService.setOnClickListener(new MyOnClickListener());
mBtnExitActivity = (Button) findViewById(R.id.btnExitActivity);
mBtnExitActivity.setOnClickListener(new MyOnClickListener());
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
}
};
class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MyService.class);
switch (v.getId()) {
case R.id.btnStartMyService:
MainActivity.this.startService(intent);
break;
case R.id.btnStopMyService:
MainActivity.this.stopService(intent);
break;
case R.id.btnBindMyService:
MainActivity.this.bindService(intent, conn, Service.BIND_AUTO_CREATE);
break;
case R.id.btnUnbindMyService:
if (MyService.ServiceState.equals("onBind")) {
MainActivity.this.unbindService(conn);
}
break;
case R.id.btnExitActivity:
MainActivity.this.finish();
break;
default:
break;
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestory");
}
}
package cn.lynn.service;
import cn.lynn.service.R;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
Button mBtnStartMyService;
Button mBtnStopMyService;
Button mBtnBindMyService;
Button mBtnUnbindMyService;
Button mBtnExitActivity;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mBtnStartMyService = (Button) findViewById(R.id.btnStartMyService);
mBtnStartMyService.setOnClickListener(new MyOnClickListener());
mBtnStopMyService = (Button) findViewById(R.id.btnStopMyService);
mBtnStopMyService.setOnClickListener(new MyOnClickListener());
mBtnBindMyService = (Button) findViewById(R.id.btnBindMyService);
mBtnBindMyService.setOnClickListener(new MyOnClickListener());
mBtnUnbindMyService = (Button) findViewById(R.id.btnUnbindMyService);
mBtnUnbindMyService.setOnClickListener(new MyOnClickListener());
mBtnExitActivity = (Button) findViewById(R.id.btnExitActivity);
mBtnExitActivity.setOnClickListener(new MyOnClickListener());
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
}
};
class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MyService.class);
switch (v.getId()) {
case R.id.btnStartMyService:
MainActivity.this.startService(intent);
break;
case R.id.btnStopMyService:
MainActivity.this.stopService(intent);
break;
case R.id.btnBindMyService:
MainActivity.this.bindService(intent, conn, Service.BIND_AUTO_CREATE);
break;
case R.id.btnUnbindMyService:
if (MyService.ServiceState.equals("onBind")) {
MainActivity.this.unbindService(conn);
}
break;
case R.id.btnExitActivity:
MainActivity.this.finish();
break;
default:
break;
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestory");
}
}MyService.java
[java]
package cn.lynn.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "MyService";
// 記錄Service生命周期的各個狀態
public static String ServiceState = "";
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
ServiceState = "onBind";
return null;
}
@Override
public boolean onUnbind(Intent intent) {
super.onUnbind(intent);
Log.i(TAG, "onUnbind");
ServiceState = "onUnbind";
return false;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
ServiceState = "onCreate";
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
ServiceState = "onStartCommand";
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
ServiceState = "onDestroy";
}
}
package cn.lynn.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "MyService";
// 記錄Service生命周期的各個狀態
public static String ServiceState = "";
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
ServiceState = "onBind";
return null;
}
@Override
public boolean onUnbind(Intent intent) {
super.onUnbind(intent);
Log.i(TAG, "onUnbind");
ServiceState = "onUnbind";
return false;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
ServiceState = "onCreate";
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
ServiceState = "onStartCommand";
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
ServiceState = "onDestroy";
}
}2.案例效果展示
點擊“StartMyService”按鈕,執行startService(...)方法,控制台LogCat輸出如下:
點擊“StopMyService”按鈕,執行stopService(...)方法,控制台LogCat輸出如下:
點擊“BindMyService”按鈕,執行bindService(...)方法,控制台LogCat輸出如下:
點擊“UnBindMyService”按鈕,執行unbindService(...)方法,控制台LogCat輸出如下:
最近在做關於能耗方面的測試,看了一個月時間的論文,終於找到了一些新的思路,但是一個問題出現了,以至於 工作無法再進行下去。 在Android手機中,對於手機
ListView是開發中最常用的控件了,但是總是會寫重復的代碼,浪費時間又沒有意義。最近參考一些資料,發現一個萬能ListView適配器,代碼量少,節省時間,總結一下分享
由於不是系統級的應用, 也沒有獲得ROOT權限, 所以自己實現任務管理器其實意義並不是很大, 就像沒有root的手機安裝了LBE這類的手機助手, 雖然也帶一鍵清理內存清理
Handler是用於操作線程內部的消息隊列的類。這有點繞,沒關系,我們慢慢的來講。前面Looper一篇講到了Looper是用於給線程創建消息隊列用的,也就是說Looper