欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Service Activity的三種交互方式(詳解)

 更新時(shí)間:2016年09月28日 10:24:30   投稿:jingxian  
下面小編就為大家?guī)硪黄猄ervice Activity的三種交互方式(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

service有兩種類型:

本地服務(wù)(Local Service):用于應(yīng)用程序內(nèi)部

遠(yuǎn)程服務(wù)(Remote Sercie):用于android系統(tǒng)內(nèi)部的應(yīng)用程序之間

前者用于實(shí)現(xiàn)應(yīng)用程序自己的一些耗時(shí)任務(wù),比如查詢升級信息,并不占用應(yīng)用程序比如Activity所屬線程,而是單開線程后臺執(zhí)行,這樣用戶體驗(yàn)比較好。

后者可被其他應(yīng)用程序復(fù)用,比如天氣預(yù)報(bào)服務(wù),其他應(yīng)用程序不需要再寫這樣的服務(wù),調(diào)用已有的即可。

編寫不需和Activity交互的本地服務(wù)示例

本地服務(wù)編寫比較簡單。首先,要?jiǎng)?chuàng)建一個(gè)Service類,該類繼承android的Service類。這里寫了一個(gè)計(jì)數(shù)服務(wù)的類,每秒鐘為計(jì)數(shù)器加一。在服務(wù)類的內(nèi)部,還創(chuàng)建了一個(gè)線程,用于實(shí)現(xiàn)后臺執(zhí)行上述業(yè)務(wù)邏輯。

Service代碼:

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;


public class CountService extends Service {
private boolean threadDisable;
private int count;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
public void run() {
while (!threadDisable) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
count++;
System.out.println(" CountService Count is " + count);
}
}
}).start();
}
@Override
public void onDestroy() {
super.onDestroy();
this.threadDisable = true;
Log.v(" CountService ", " on destroy ");
}
}
將該服務(wù)注冊到配置文件AndroidManifest.xml中
<service android:name="CountService" />
在Activity中啟動(dòng)和關(guān)閉本地服務(wù)
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;


public class LocalServiceDemoActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.startService(new Intent(this, CountService.class));
}


@Override
protected void onDestroy() {
super.onDestroy();
this.stopService(new Intent(this, CountService.class));
}
}

編寫本地服務(wù)和Activity交互的示例

上面的示例是通過startService和stopService啟動(dòng)關(guān)閉服務(wù)的。適用于服務(wù)和activity之間沒有調(diào)用交互的情況。如果之間需要傳遞參數(shù)或者方法調(diào)用。需要使用bind和unbind方法。

具體做法是,服務(wù)類需要增加接口,比如ICountService,另外,服務(wù)類需要有一個(gè)內(nèi)部類,這樣可以方便訪問外部類的封裝數(shù)據(jù),這個(gè)內(nèi)部類需要繼承Binder類并實(shí)現(xiàn)ICountService接口。還有,就是要實(shí)現(xiàn)Service的

onBind方法,不能只傳回一個(gè)null了。

新建立的接口代碼:

public interface ICountService {
public abstract int getCount();
}

CountService代碼:
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;


public class CountService extends Service implements ICountService {
private boolean threadDisable;
private int count;
private ServiceBinder serviceBinder = new ServiceBinder();


public class ServiceBinder extends Binder implements ICountService {
// @Override
public int getCount() {
return count;
}
}


@Override
public IBinder onBind(Intent intent) {
return serviceBinder;
}


@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
// @Override
public void run() {
while (!threadDisable) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
count++;
System.out.println("CountService Count is " + count);
}
}
}).start();
}


@Override
public void onDestroy() {
super.onDestroy();
this.threadDisable = true;
Log.v(" CountService ", " on destroy ");
}


// @Override
public int getCount() {
return count;
}
}

服務(wù)的注冊也要做改動(dòng),AndroidManifest.xml文件:

 <service android:name="CountService" >
      <intent-filter>
        <action android:name="com.phone.jiaohuservice.CountService" />
      </intent-filter>
 </service>

Acitity代碼不再通過startSerivce和stopService啟動(dòng)關(guān)閉服務(wù),另外,需要通過ServiceConnection的內(nèi)部類實(shí)現(xiàn)來連接Service和Activity。
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;


public class LocalServiceDemoActivity extends Activity {
private ServiceConnection serviceConnection = new ServiceConnection() {
// @Override
public void onServiceConnected(ComponentName name, IBinder service) {
countService = (ICountService) service;
System.out.println(" CountService on serivce connected, count is "
+ countService.getCount());
}


// @Override
public void onServiceDisconnected(ComponentName name) {
countService = null;
}
};


private ICountService countService;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.bindService(new Intent("com.phone.jiaohuservice.CountService"),
this.serviceConnection, BIND_AUTO_CREATE);
}


@Override
protected void onDestroy() {
this.unbindService(serviceConnection);
super.onDestroy(); // 注意先后
}
}

編寫傳遞基本型數(shù)據(jù)的遠(yuǎn)程服務(wù)

上面的示例,可以擴(kuò)展為,讓其他應(yīng)用程序復(fù)用該服務(wù)。這樣的服務(wù)叫遠(yuǎn)程(remote)服務(wù),實(shí)際上是進(jìn)程間通信(RPC)。

這時(shí)需要使用android接口描述語言(AIDL)來定義遠(yuǎn)程服務(wù)的接口,而不是上述那樣簡單的java接口。擴(kuò)展名為aidl而不是java??捎蒙厦娴腎CountService改動(dòng)而成ICountSerivde.aidl,eclipse會自動(dòng)生成相關(guān)的java文件。

遠(yuǎn)端代碼:

ICountService.aidl

package com.phone.remoteservice.aidl;
interface ICountService {
int getCount();
} 

CountService.java

import com.phone.remoteservice.aidl.ICountService;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;


public class CountService extends Service {
private boolean threadDisable;
private int count;
private ICountService.Stub serviceBinder = new ICountService.Stub() {
// @Override
public int getCount() throws RemoteException {
return count;
}
};


// @Override
public IBinder onBind(Intent intent) {
return serviceBinder;
}


@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
// @Override
public void run() {
while (!threadDisable) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
count++;
Log.i("aa", "---" + count + "---");
}
}
}).start();
}


// @Override
public void onDestroy() {
super.onDestroy();
this.threadDisable = true;
Log.v(" CountService ", " on destroy ");
}

}

 配置文件AndroidManifest.xml

<service android:name=".CountService" >
 <intent-filter>
 <action android:name="com.phone.remoteservice.CountService" />
 </intent-filter>
</service>

本地代碼:

拷貝遠(yuǎn)端代碼gen:com.phone.remoteservice.aidl包名及內(nèi)部生成的ICountService.java文件到本地,注意包名不要變,java文件名也不要變。

測試代碼

import com.phone.remoteservice.aidl.ICountService;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;


public class RemoteServiceTest extends Activity {
private ICountService countService;
private boolean SreviceDisable;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bindService(new Intent("com.phone.remoteservice.CountService"),
this.serviceConnection, BIND_AUTO_CREATE);
}


@Override
protected void onDestroy() {
this.unbindService(serviceConnection);
SreviceDisable = true;
super.onDestroy(); // 注意先后
}


private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
countService = ICountService.Stub.asInterface(service);
new Thread(new Runnable() {
// @Override
public void run() {
while (!SreviceDisable) {

try {
System.out
.println(" CountService on serivce connected, count is "
+ countService.getCount());
} catch (RemoteException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}).start();
}


public void onServiceDisconnected(ComponentName name) {
countService = null;

}
};
}

在Activity中使用服務(wù)的差別不大,只需要對ServiceConnection中的調(diào)用遠(yuǎn)程服務(wù)的方法時(shí),要捕獲RemoteException 異常。

這樣就可以在同一個(gè)應(yīng)用程序中使用遠(yuǎn)程服務(wù)的方式和自己定義的服務(wù)交互了。 如果是另外的應(yīng)用程序使用遠(yuǎn)程服務(wù),需要做的是復(fù)制上面的aidl文件和相應(yīng)的包構(gòu)到應(yīng)用程序中,其他調(diào)用等都一樣。

編寫傳遞復(fù)雜數(shù)據(jù)類型的遠(yuǎn)程服務(wù)

遠(yuǎn)程服務(wù)往往不只是傳遞java基本數(shù)據(jù)類型。這時(shí)需要注意android的一些限制和規(guī)定:

1. android支持String和CharSequence

2. 如果需要在aidl中使用其他aidl接口類型,需要import,即使是在相同包結(jié)構(gòu)下;

3. android允許傳遞實(shí)現(xiàn)Parcelable接口的類,需要import;

4. android支持集合接口類型List和Map,但是有一些限制,元素必須是基本型或者上述三種情況,不需要import集合接口類,但是需要對元素涉及到的類型import;

5. 非基本數(shù)據(jù)類型,也不是String和CharSequence類型的,需要有方向指示,包括in、out和inout,in表示由客戶端設(shè)置,out表示由服務(wù)端設(shè)置,inout是兩者均可設(shè)置。

這里將前面的例子中返回的int數(shù)據(jù)改為復(fù)雜數(shù)據(jù)類型:

import android.os.Parcel;
import android.os.Parcelable;
public class CountBean implements Parcelable {
public static final Parcelable.Creator < CountBean > CREATOR = new Creator < CountBean > () {
@Override
public CountBean createFromParcel(Parcel source) {
CountBean bean = new CountBean();
bean.count = source.readInt();
return bean;
}
@Override
public CountBean[] newArray( int size) {
return new CountBean[size];
}
};
public int count;
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt( this .count);
}
@Override
public int describeContents() {
return 0 ;
}
}

以上就是小編為大家?guī)淼腟ervice Activity的三種交互方式(詳解)的全部內(nèi)容了,希望對大家有所幫助,多多支持腳本之家~

相關(guān)文章

最新評論