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; } }