service和activity之間的數據交互 (從activity傳數據給service,又從service傳數據給activity),這樣的使用在安卓開發中是比較有深度的使用方式。下面我們就來介紹一下它的使用。
整體思路:在xml文件中放置一個TextView控件,三個Button控件,定義一個MyService類,繼承Service,在onBind方法中返回LocalBinder對象,定義getRandom方法,返回一個隨機數,定義一個LocalBinder類,繼承Binder,在這個類中定義getService方法返回service對象,重寫onTransact方法接收從activity中傳遞的數據並向activity中傳遞數據。在activity中,定義三個Button的點擊事件,在第一個點擊事件中綁定Service,在第二個點擊事件中調用service的產生隨機數的方法,並將獲取的結果綁定到TextView控件上,在第三個點擊事件中向service傳遞數據並獲取從service中傳遞的數據。這樣就完成了service和activity之間的數據交互。
activity_main.xml文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="51dp"
android:text="@string/hello_world" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="37dp"
android:text="綁定service服務" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button1"
android:layout_centerHorizontal="true"
android:layout_marginTop="21dp"
android:text="調用service的方法" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button2"
android:layout_centerHorizontal="true"
android:layout_marginTop="23dp"
android:text="和service之間的數據交互" />
</RelativeLayout>
MyService.java文件:
package com.example.android_service_tran;
//service和activity之間的數據交互
//先從activity傳給myservice兩個值並輸出,然後再從myservice傳給activity兩個值並輸出
import java.util.Random;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.widget.Toast;
public class MyService extends Service {
private final Random random=new Random();
private LocalBinder binder=new LocalBinder();
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return binder;
}
// service服務中的方法
public int getRandom(){
return random.nextInt(100);
}
public class LocalBinder extends Binder{
public MyService getService(){
return MyService.this;
}
@Override
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "-MyService-readInt->"+data.readInt(), 1).show();
Toast.makeText(getApplicationContext(), "-MyService-readString->"+data.readString(), 1).show();
// 使用reply回傳兩個值
reply.writeString("rose");
reply.writeInt(getRandom());
return super.onTransact(code, data, reply, flags);
}
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
}
MainActivity.java文件:
package com.example.android_service_tran;
import java.sql.Connection;
import com.example.android_service_tran.MyService.LocalBinder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private Button button,button2,button3;
private TextView textView;
private boolean flag=false;//是否綁定服務的標誌位
private LocalBinder localBinder;//服務中的對象
private MyService myService;//聲明一個MyService對象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button)findViewById(R.id.button1);
button2=(Button)findViewById(R.id.button2);
button3=(Button)findViewById(R.id.button3);
textView=(TextView)findViewById(R.id.textView1);
// 綁定service
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
// 綁定service的服務
Intent intent=new Intent(MainActivity.this,MyService.class);
// 啓動service
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
});
// 調用service的方法
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(flag){
int random=myService.getRandom();
textView.setText("-->"+random);
}
}
});
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
// activity傳了兩個值
Parcel data=Parcel.obtain();
data.writeInt(23);
data.writeString("Jack");
Parcel reply=Parcel.obtain();
try {
localBinder.transact(IBinder.LAST_CALL_TRANSACTION, data, reply, 0);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
Toast.makeText(MainActivity.this, "MainActivity-readString:"+reply.readString(), 1).show();
Toast.makeText(MainActivity.this, "MainActivity-readInt:"+reply.readInt(), 1).show();
}
});
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
if(flag){
unbindService(connection);
flag=false;
}
}
// 連接activity和service之間的一個橋樑
public ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
flag=false;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
localBinder=(LocalBinder)service;
myService=localBinder.getService();
flag=true;
}
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}