最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

第七章 后臺服務(wù)(本地服務(wù))

2018-11-11 23:43 作者:swiss126  | 我要投稿

?參考資料:

《Android應(yīng)用程序開發(fā)》ISBN 9787302283164

參考軟件:

Android Studio、Eclipse+ADT、Android SDK、JDK

本地服務(wù)

本地服務(wù)的調(diào)用者和服務(wù)都在同一個程序中,是不需要跨進(jìn)程就可以實(shí)現(xiàn)服務(wù)的調(diào)用

  • 步驟1:新建子類繼承Service類

    需重寫父類的onCreate()、onStartCommand()、onDestroy()和onBind()方法

  • 步驟2:構(gòu)建用于啟動Service的Intent對象

  • 步驟3:調(diào)用startService()啟動Service、調(diào)用stopService()停止服務(wù)


步驟4:在AndroidManifest.xml里注冊Service

一、實(shí)現(xiàn)啟動服務(wù)(1)界面實(shí)現(xiàn)


<?xml?version="1.0"??encoding="utf-8"?>

?

<LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"

?

??? ?android:orientation="vertical"

?

??? ?android:layout_width="fill_parent"

?

??? ?android:layout_height="fill_parent"

?

??? ?>

?

??<TextView? ?android:id="@+id/label"

?

??? ?android:layout_width="fill_parent"??

?

??? ?android:layout_height="wrap_content"??

?

??? ?android:text="@string/hello">

?

??</TextView>

?

??<Button?android:id="@+id/start"??

?

?????android:layout_width="wrap_content"

?

?????android:layout_height="wrap_content"

?

?????android:text="啟動Service"?>

?

??</Button>

?

??<Button?android:id="@+id/stop"??

?

?????android:layout_width="wrap_content"

?

?????android:layout_height="wrap_content"

?

?????android:text="停止Service"?>

?

??</Button>

?

</LinearLayout>

?

?

?

(2)建立Service類

?

?

package ?edu.hrbeu.SimpleRandomServiceDemo;

?

?

?

import android.app.Service;

?

import android.content.Intent;

?

import android.os.IBinder;

?

import android.widget.Toast;

?

?

?

public class RandomService extends ?Service{

?

????????

?

???????? @Override

?

???????? public ?void onCreate() {

?

???????? ??? super.onCreate();

?

???????? ??? Toast.makeText(this, "(1)?調(diào)用onCreate()",

?

???????? ??? ?????????????????? Toast.LENGTH_LONG).show();???

?

???????? }

?

????????

?

???????? @Override

?

???????? public ?void onStart(Intent intent, int startId) {

?

???????? ????? super.onStart(intent, startId);

?

???????? ????? Toast.makeText(this, "(2)?調(diào)用onStart()",

?

???????? ??? ?????????????????? ??Toast.LENGTH_SHORT).show();

?

?

?

???????? ????? double randomDouble = Math.random();

?

???????? ????? String msg = "隨機(jī)數(shù):"+ String.valueOf(randomDouble);

?

???????? ????? Toast.makeText(this,msg, ?Toast.LENGTH_SHORT).show();

?

???????? }

?

????????

?

???????? @Override

?

???????? public ?void onDestroy() {

?

???????? ???? super.onDestroy();

?

???????? ???? Toast.makeText(this, "(3)?調(diào)用onDestroy()",

?

???????? ??? ?????????????????? ?Toast.LENGTH_SHORT).show();????

?

???????? }

?

???????? ?

?

????????

?

???????? @Override

?

???????? public ?IBinder onBind(Intent intent) {

?

?????????????????? return ?null;

?

???????? }

?

?

?

}

?

(3)注冊Service

?

?

<service ?android:name=".RandomService"/>

?

(4)實(shí)現(xiàn)啟動和停止

顯示啟動

1??? ?final Intent serviceIntent = new Intent(this, RandomService.class);

?

2??? ?startService(serviceIntent);

?

?

?

?

?

隱式啟動

?

?

?

1??? ?<service android:name=".RandomService">

?

2??????? ?<intent-filter>

?

3??????????? <action ?android:name="edu.hrbeu.RandomService" />

?

4??????? ?</intent-filter>

?

5??? ?</service>

?

?

?

?

?

?

?

?

?

package edu.hrbeu.SimpleRandomServiceDemo;

?

?

?

import android.app.Activity;

?

import android.content.Intent;

?

import android.os.Bundle;

?

import android.view.View;

?

import android.widget.Button;

?

?

?

public class ?SimpleRandomServiceDemoActivity extends Activity {

?

??? ?/** Called when the activity is first created. */

?

??? ?@Override

?

??? ?public void onCreate(Bundle savedInstanceState) {

?

??????? ?super.onCreate(savedInstanceState);

?

??????? ?setContentView(R.layout.main);

?

??????? ?

?

??????? ?Button startButton = (Button)findViewById(R.id.start);

?

??????? ?Button stopButton = (Button)findViewById(R.id.stop);

?

??????? ?

?

??????? ?final Intent serviceIntent = new Intent(this, RandomService.class);

?

??????? ?

?

??????? ?startButton.setOnClickListener(new Button.OnClickListener(){

?

??????? ????????? public void onClick(View ?view){

?

??????? ??????????????????? startService(serviceIntent);

?

??????? ????????? }

?

??????? ?});

?

??????? ?

?

??????? ?stopButton.setOnClickListener(new Button.OnClickListener(){

?

??????? ????????? public void onClick(View ?view){

?

??????? ??????????????????? stopService(serviceIntent);

?

??????? ????????? }

?

??????? ?});

?

? ??}

?

}

?

停止一個started服務(wù)有兩種方法:

(1)在外部使用stopService()

(2)在服務(wù)內(nèi)部(onStartCommand方法內(nèi)部)使用stopSelf()方法。

?

(5)查看

我們還可以在正在“設(shè)置--應(yīng)用---運(yùn)行”中找到這個服務(wù),如下圖所示:

點(diǎn)開上圖中的紅框部分,可以看到:


Android獲取手機(jī)狀態(tài)和監(jiān)聽手機(jī)來電狀態(tài)例子

獲取手機(jī)狀態(tài):


import?android.content.Context;??



import?android.telephony.TelephonyManager;??



??



//獲得相應(yīng)的系統(tǒng)服務(wù)??



TelephonyManager?tm?=?(TelephonyManager)?getSystemService(Context.TELEPHONY_SERVICE);??



???????/**?



????????*?返回電話狀態(tài)?



????????*??



????????*?CALL_STATE_IDLE?無任何狀態(tài)時??



????????*?CALL_STATE_OFFHOOK?接起電話時?



????????*?CALL_STATE_RINGING?電話進(jìn)來時??



????????*/??



???????tm.getCallState();??



???????if(tm.getCallState()?==?TelephonyManager.CALL_STATE_IDLE)?{??



????????Log.d("test",?"call?state?idle...");??



???????}?else?if(tm.getCallState()?==?TelephonyManager.CALL_STATE_OFFHOOK)?{??



????????Log.d("test",?"call?state?offhook...");??



???????}?else?if(tm.getCallState()?==?TelephonyManager.CALL_STATE_RINGING)?{??



????????Log.d("test",?"call?state?ringing...");??



???????} ?


監(jiān)聽手機(jī)來電狀態(tài):


TelephonyManager?tm?=?(TelephonyManager)?getSystemService(Context.TELEPHONY_SERVICE);??



??



//使用TelephonyManager對象的listen(PhoneStateListener?listener,?int?events)??



??



??



//實(shí)現(xiàn)PhoneStateListener?listener并實(shí)現(xiàn)相應(yīng)的方法??



??



public?class?MyPhoneCallListener?extends?PhoneStateListener??



{??



??



@Override??



public?void?onCallStateChanged(int?state,?String?incomingNumber)??



{??



??



??switch?(state)?{??



????case?TelephonyManager.CALL_STATE_OFFHOOK:???????????????????//電話通話的狀態(tài)??



????????Toast.makeText(Main.this,?"正在通話...",?Toast.LENGTH_SHORT).show();??



????????break;??



??



????case?TelephonyManager.CALL_STATE_RINGING:???????????????????//電話響鈴的狀態(tài)??



????????Toast.makeText(Main.this,?incomingNumber,?Toast.LENGTH_SHORT).show();??



????????break;??



??}??



??super.onCallStateChanged(state,?incomingNumber);??



} ?


第一個參數(shù)需要實(shí)現(xiàn)PhoneStateListener listener并實(shí)現(xiàn)相應(yīng)的方法,第二個參數(shù)是PhoneStateListener的靜態(tài)常量,此處由于是監(jiān)聽電話狀態(tài),所以需要傳入LISTEN_CALL_STATE,而同時也需要在AndroidManifest中注冊相應(yīng)的權(quán)限

<uses-permission?Android:name="android.permission.READ_PHONE_STATE" />


二、實(shí)現(xiàn)綁定服務(wù)

以綁定方式使用Service,能夠獲取到Service實(shí)例,不僅能夠正常啟動Service,還能夠調(diào)用Service中的公有方法和屬性


應(yīng)用程序組件(客戶端)通過調(diào)用bindService()方法能夠綁定服務(wù),然后Android系統(tǒng)會調(diào)用服務(wù)的onBind()回調(diào)方法,則個方法會返回一個跟服務(wù)器端交互的Binder對象。

這個綁定是異步的,bindService()方法立即返回,并且不給客戶端返回IBinder對象。要接收IBinder對象,客戶端必須創(chuàng)建一個ServiceConnection類的實(shí)例,并且把這個實(shí)例傳遞給bindService()方法。ServiceConnection對象包含了一個系統(tǒng)調(diào)用的傳遞IBinder對象的回調(diào)方法。

注意:只有Activity、Service、Content Provider能夠綁定服務(wù);BroadcastReceiver廣播接收器不能綁定服務(wù)。

?

(1)界面實(shí)現(xiàn)

?

?

<?xml?version="1.0"??encoding="utf-8"?>

?

<LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"

?

??? ?android:orientation="vertical"

?

??? ?android:layout_width="fill_parent"

?

?? ??android:layout_height="fill_parent"

?

??? ?>

?

??<TextView? ?android:id="@+id/label"

?

??? ?android:layout_width="fill_parent"??

?

??? ?android:layout_height="wrap_content"??

?

??? ?android:text="@string/hello">

?

??</TextView>

?

??<Button?android:id="@+id/bind"??

?

?????android:layout_width="wrap_content"

?

?????android:layout_height="wrap_content"

?

?????android:text="服務(wù)綁定"?>

?

??</Button>

?

?????<Button?android:id="@+id/unbind"??

?

?????android:layout_width="wrap_content"

?

?????android:layout_height="wrap_content"

?

?????android:text="取消綁定"?>

?

??</Button>

?

??<Button?android:id="@+id/compute"??

?

?????android:layout_width="wrap_content"

?

?????android:layout_height="wrap_content"

?

?????android:text="加法運(yùn)算"?>

?

??</Button>

?

</LinearLayout>

?

?

?

?

(2)建立服務(wù)類

?

?

package edu.hrbeu.SimpleMathServiceDemo;

?

?

?

import android.app.Service;

?

import android.content.Intent;

?

import android.os.Binder;

?

import android.os.IBinder;

?

import android.widget.Toast;

?

?

?

public class MathService extends Service{

?

?

?

???????? private ?final IBinder mBinder = new LocalBinder();

?

?

?

???????? public ?class LocalBinder extends Binder{

?

?????????????????? MathService ?getService() {

?

??????????????????????????? return ?MathService.this;

?

???????? ??? }

?

???????? }

?

?

?

???????? @Override

?

???????? public ?IBinder onBind(Intent intent) {

?

?????????????????? ?Toast.makeText(this, "本地綁定:MathService",

?

???????? ???? ??????????????? ??Toast.LENGTH_SHORT).show();

?

?????????????????? return ?mBinder;

?

???????? }

?

????????

?

???????? @Override

?

???????? public ?boolean onUnbind(Intent intent){

?

?????????????????? ? Toast.makeText(this, "取消本地綁定:MathService",

?

?????????????????? ??? ?????????????????? ?Toast.LENGTH_SHORT).show();?

?

?????????????????? return ?false;

?

???????? }

?

????????

?

?

?

???????? public ?long Add(long a, long b){

?

?????????????????? return ?a+b;

?

???????? }

?

????????

?

}

?

?

(3)注冊

?

?

<service android:name=".MathService"/>

?

(4)實(shí)現(xiàn)啟動和停止

?

?

package edu.hrbeu.SimpleMathServiceDemo;

?

?

?

import android.app.Activity;

?

import android.content.ComponentName;

?

import android.content.Context;

?

import android.content.Intent;

?

import android.content.ServiceConnection;

?

import android.os.Bundle;

?

import android.os.IBinder;

?

import android.view.View;

?

import android.widget.Button;

?

import android.widget.TextView;

?

?

?

public class SimpleMathServiceDemoActivity ?extends Activity {

?

???????? private ?MathService mathService;

?

???????? private ?boolean isBound = false;

?

???????? TextView ?labelView;

?

??? ?@Override

?

??? ?public void onCreate(Bundle savedInstanceState) {

?

??????? ?super.onCreate(savedInstanceState);

?

??????? ?setContentView(R.layout.main);

?

??????? ?

?

??????? ?labelView = (TextView)findViewById(R.id.label);

?

??????? ?Button bindButton = (Button)findViewById(R.id.bind);

?

??????? ?Button unbindButton = (Button)findViewById(R.id.unbind);

?

??????? ?Button computButton = (Button)findViewById(R.id.compute);

?

??????? ?

?

??????? ?bindButton.setOnClickListener(new View.OnClickListener(){

?

??????????????????????????? @Override

?

??????????????????????????? public ?void onClick(View v) {

?

???????????????????????????????????? if(!isBound){

?

?????????????????????????????????????????????? final ?Intent serviceIntent = new ?Intent(SimpleMathServiceDemoActivity.this,MathService.class);

?

?????????????????????????????????????????????? bindService(serviceIntent,mConnection,Context.BIND_AUTO_CREATE);

?

?????????????????????????????????????????????? isBound ?= true;

?

???????????????????????????????????? }

?

??????????????????????????? }? ??

?

??????? ?});

?

??????? ?

?

??????? ?unbindButton.setOnClickListener(new View.OnClickListener(){

?

??????????????????????????? @Override

?

??????????????????????????? public ?void onClick(View v) {

?

???????????????????????????????????? if(isBound){

?

?????????????????????????????????????????????? isBound ?= false;

?

?????????????????????????????????????????????? unbindService(mConnection);

?

?????????????????????????????????????????????? mathService ?= null;

?

???????????????????????????????????? }

?

??????????????????????????? }??? ???????

?

??????? ?});

?

??????? ?

?

??????? ?computButton.setOnClickListener(new View.OnClickListener(){

?

??????????????????????????? @Override

?

??????????????????????????? public ?void onClick(View v) {

?

?????????????????????????????????????????????? if ?(mathService == null){

?

??????????????????????????????????????????????????????? labelView.setText("未綁定服務(wù)");

?

??????????????????????????????????????????????????????? return;

?

?????????????????????????????????????????????? }

?

?????????????????????????????????????????????? long ?a = Math.round(Math.random()*100);

?

?????????????????????????????????????????????? long ?b = Math.round(Math.random()*100);

?

?????????????????????????????????????????????? long ?result = mathService.Add(a, b);

?

?????????????????????????????????????????????? String ?msg = String.valueOf(a)+" + "+String.valueOf(b)+

?

??????????????????????????????????????????????????????????????????????????????????? " ?= "+String.valueOf(result);

?

?????????????????????????????????????????????? labelView.setText(msg);

?

??????????????????????????? } ??????

?

??????? ?});

?

?

?

??? ?}

?

??? ?

?

??? ?private ServiceConnection mConnection = new ServiceConnection() {

?

?????????????????? @Override

?

?????????????????? public ?void onServiceConnected(ComponentName name, IBinder service) {

?

???????? ?????????????????? mathService = ?((MathService.LocalBinder)service).getService();

?

?????????????????? }

?

?

?

?????????????????? @Override

?

?????????????????? public ?void onServiceDisconnected(ComponentName name) {

?

??????????????????????????? mathService ?= null;?

?

?????????????????? }

?

??? ?};

?

}

?三、IntentService(多線程)

IntentService是Android里面的一個封裝類,繼承自四大組件之一的Service。

作用是:處理異步請求,實(shí)現(xiàn)多線程

1.?工作流程

工作流程

注意:若啟動IntentService?多次,那么每個耗時操作則以隊(duì)列的方式在?IntentService的onHandleIntent回調(diào)方法中依次執(zhí)行,執(zhí)行完自動結(jié)束。

2.?實(shí)現(xiàn)步驟

·????????步驟1:定義IntentService的子類:傳入線程名稱、復(fù)寫onHandleIntent()方法

·????????步驟2:在Manifest.xml中注冊服務(wù)

·????????步驟3:在Activity中開啟Service服務(wù)

3.?例子

服務(wù)中的代碼默認(rèn)運(yùn)行在主線程中,如果直接在服務(wù)里執(zhí)行一些耗時操作,容易造成ANR(Application NotResponding)異常,所以就需要用到多線程的知識了。

一個比較標(biāo)準(zhǔn)的服務(wù)可以這樣寫

?

?

package com.example.servicetest;

?

?

?

import android.app.Service;

?

import android.content.Intent;

?

import android.os.IBinder;

?

?

?

public class MyService extends Service ?{?

?

????? ?

?

??? ?public static final String TAG = "MyService";??

?

?

?

??? ?//服務(wù)執(zhí)行的操作

?

??? ?@Override?

?

??? ?public int onStartCommand(Intent intent, int flags, int startId) ?{?

?

??????? ?new Thread(new Runnable() {

?

??????????? public void run() {

?

??????????????? //處理具體的邏輯

?

??????????????? stopSelf();? //服務(wù)執(zhí)行完畢后自動停止

?

??????????? }

?

??????? ?}).start();???????

?

??????? ?return super.onStartCommand(intent, flags, startId);?

?

??? ?}

?

?

?

??? ?@Override

?

??? ?public IBinder onBind(Intent intent) {

?

??????? ?// TODO Auto-generated method stub

?

??????? ?return null;

?

??? ?}?????

?

?

?

}

?

(1)新建一個MyIntentService類

?

?

package com.example.servicetest;

?

?

?

import android.app.IntentService;

?

import android.content.Intent;

?

import android.util.Log;

?

?

?

public class MyIntentService extends ?IntentService{

?

?

?

??? ?public MyIntentService() {

?

??????? ?super("MyIntentService");//調(diào)用父類有參構(gòu)造函數(shù)。這里我們手動給服務(wù)起個名字為:MyIntentService

?

??????? ?// TODO Auto-generated constructor stub

?

??? ?}

?

?

?

??? ?//該方法在會在一個單獨(dú)的線程中執(zhí)行,來完成工作任務(wù)。任務(wù)結(jié)束后,該Service自動停止

?

??? ?@Override

?

??? ?protected void onHandleIntent(Intent intent) {

?

??????? ?// TODO Auto-generated method stub

?

??????? ?for(int i = 0;i<3;i++) {

?

??????????? //打印當(dāng)前線程的id

?

??????????? ?Log.d("MyIntentService","IntentService線程的id是:"+Thread.currentThread().getId());

?

??????????? try {

?

????? ???????????Thread.sleep(1000);

?

??????????? } catch (InterruptedException e) ?{

?

??????????????? // TODO Auto-generated catch ?block

?

??????????????? e.printStackTrace();

?

??????????? }

?

??????? ?}???????

?

??? ?}

?

?

?

??? ?@Override

?

??? ?public void onDestroy() {

?

??????? ?// TODO Auto-generated method stub

?

??????? ?super.onDestroy();

?

??????? ?Log.d("MyIntentService","onDestroy");

?

??? ?}

?

}

?

(2)在清單文件中對服務(wù)進(jìn)行注冊服務(wù)

?

?

<service?android:name=".MyIntentService"></service>

?

?

?

(3)實(shí)現(xiàn)啟動

在activity_main.xml中添加一個按鈕button3_stop_intentservice,用于啟動MyIntentService服務(wù),代碼略

?

?

case?R.id.button3_stop_intentservice:

2?????????????Log.d("MainActivity","主線程的id是:"+Thread.currentThread().getId());

3?????????????Intent?intentService?=?new?Intent(this,MyIntentService.class);

4?????????????startService(intentService);

5?????????default:

?

?

?

3.?總結(jié)


  • 從上面源碼可以看出,IntentService本質(zhì)是采用Handler & HandlerThread方式:

    1. 通過HandlerThread單獨(dú)開啟一個名為IntentService的線程

    2. 創(chuàng)建一個名叫ServiceHandler的內(nèi)部Handler

    3. 把內(nèi)部Handler與HandlerThread所對應(yīng)的子線程進(jìn)行綁定

    4. 通過onStartCommand()傳遞給服務(wù)intent,依次插入到工作隊(duì)列中,并逐個發(fā)送給onHandleIntent()

    5. 通過onHandleIntent()來依次處理所有Intent請求對象所對應(yīng)的任務(wù)

因此我們通過復(fù)寫方法onHandleIntent(),再在里面根據(jù)Intent的不同進(jìn)行不同的線程操作就可以了


第七章 后臺服務(wù)(本地服務(wù))的評論 (共 條)

分享到微博請遵守國家法律
富裕县| 万荣县| 东明县| 龙山县| 舞钢市| 乐山市| 德阳市| 武隆县| 镇原县| 高密市| 根河市| 外汇| 陆丰市| 宽城| 封开县| 如皋市| 潼关县| 咸阳市| 西安市| 焉耆| 河间市| 加查县| 菏泽市| 新兴县| 中江县| 武乡县| 淄博市| 石阡县| 满城县| 木兰县| 大冶市| 土默特左旗| 江华| 平乡县| 河源市| 高碑店市| 肥东县| 孟州市| 叶城县| 庆云县| 东兰县|