package com.service.service; import com.example.service.R; 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.os.RemoteException; import android.view.View; import android.widget.Toast; /** * service组件 * 1.定义一个类继承Service类 * Service两种启动方式 * <1>.start * <2>.onBind * 服务对象同时只有一个 * 默认情况下,一个started的service与启动它的应用组件在同一线程中, * 所以如果我们使用service来完成一些好使的操作任务时,就会阻塞主线程 * 那我们就必须在线程中来处理耗时任务 * 停止一个服务的两种方法 * <1>.在外部使用stopService() * <2>.在服务类内部使用stopSelf() * * IntentService * 该类型的service会在单独的线程中执行任务,任务完成后会自动结束service * 当我们有需要这样一次性完成的任务就可以使用IntentService来完成 * * * * IPC(进程间的通讯) * AIDL(android接口定义语言) * 使用aidl定义业务接口,通过ADT工具来生成一个java类,此类实现了进程间远程通讯的代理 * 编写自己的业务类(继承生成的类中的stub存根)来实现业务接口 * 再通过绑定service的方式来暴露此业务对象给其他组件提供功能 * * 调用者组件通过servuce方法绑定服务,从而可以获取绑定成功后的远程业务对象或本地对象 * 可以调用相关的功能 * 注意:一般在使用完绑定服务后,需要解除绑定 * * 自定义AIDL对象 * 1.需要自自定义的类型上实现Parcelable接口 * 2.需要定义一个aidl文件来申明自定义类型(在student。aidl文件中申明 parcelable Student;) * 3.在使用该自定义类型时必须使用import语句导入该自定义类型,否则报错 * * * * 使用started与bing服务之间的区别 * 使用started会一直运行在后台,需要服务本身或外部组件停止服务才会结束运行 * 通过bind的服务,它的生命周期依赖绑定的组件, * 1.started服务可以给启动的对象传递参数,但无法获取服务中的方法返回 * 2.可以给启动的服务对象传递参数,也可以通过绑定的业务对象获取返回结果 * 在实际应用中的使用技巧 * 1.第一次先使用started来启动一个服务, * 之后可以使用绑定的方式绑定服务,从而可以直接调用业务方法返回值 * */ public class MainActivity extends Activity { private IPerson person; //要使用的业务对象接口 boolean flag=false; //服务连接对象 private ServiceConnection serviceConnection=new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub //当服务异常终止时会调用,注意:解除绑定服务时不会调用 System.out.println("onServiceDisconnected"); flag=false; } @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub //绑定成功后服务会回调该方法,自动传入IBinder对象 System.out.println("onServiceConnected"); person= IPerson.Stub.asInterface(service); System.out.println(person); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /** * 启动一个服务 * */ public void start1(View view){ System.out.println("start1"); Intent intent=new Intent(this,HelloService.class); startService(intent); } public void stop(View view){ System.out.println("stop"); Intent intent=new Intent(this,HelloService.class); stopService(intent); } public void start2(View view){ Intent intent=new Intent(this,HelloIntentService.class); startService(intent); } //绑定一个服务 public void bindService(View view){ System.out.println("bindService"); Intent intent=new Intent(this,MyService.class); //参数(1.intent对象,2.服务连接对象,3.绑定服务的标记) flag=bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } //解除绑定服务 public void unBindService(View view){ if(flag){ unbindService(serviceConnection); flag=false; } } //调用远程业务对象方法(或是本地业务) public void callPerson(View view) throws RemoteException{ person.setName("张三"); person.setAge(21); person.setSex("男"); String s=person.getPerson(); Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show(); }
activity_main.xml
<LinearLayout 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="com.service.service.MainActivity" android:orientation="vertical" > <Button android:id="@+id/activity1_button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="启动service1" android:onClick="start1" /> <Button android:id="@+id/activity1_button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="停止service1" android:onClick="stop" /> <Button android:id="@+id/activity1_button3" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="startIntentService" android:onClick="start2" /> <Button android:id="@+id/activity1_button4" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="绑定Service" android:onClick="bindService" /> <Button android:id="@+id/activity1_button5" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="解绑Service" android:onClick="unBindService" /> <Button android:id="@+id/activity1_callPerson" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="调用业务对象Person的方法" android:onClick="callPerson" /> </LinearLayout>
HelloService
package com.service.service; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class HelloService extends Service{ private PersonImpl personImpl; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return new PersonImpl(); } //创建服务时调用 @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Log.i("HelloService", "HelloServiceOnCreate"); } //销毁服务时调用 @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.i("HelloService", "HelloServiceONDestory"); } //服务执行时的操作 @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.i("HelloService", "HelloServiceONStartCommand"); System.out.println("HelloServiceONStartCommand"); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub int i=0; for(;i<10;i++){ System.out.println(Thread.currentThread().getName()+":"+i); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //HelloService.this.stopSelf(); //停止服务 } }).start(); return super.onStartCommand(intent, flags, startId); } }
IPerson.aidl文件
package com.service.service; interface IPerson { void setName(String name); void setSex(String sex); void setAge(int age); String getPerson(); }
PersonImpl
package com.service.service; import android.os.RemoteException; public class PersonImpl extends IPerson.Stub { private String name; private String sex; private int age; @Override public void setName(String name) throws RemoteException { // TODO Auto-generated method stub this.name=name; } @Override public void setSex(String sex) throws RemoteException { // TODO Auto-generated method stub this.sex=sex; } @Override public void setAge(int age) throws RemoteException { // TODO Auto-generated method stub this.age=age; } @Override public String getPerson() throws RemoteException { // TODO Auto-generated method stub return "name="+name+"sex="+sex+"age="+age; } }
第二种:继承IntentService
HelloIntentService
package com.service.service; import android.app.IntentService; import android.content.Intent; public class HelloIntentService extends IntentService{ public HelloIntentService() { super("IntentSerice"); // TODO Auto-generated constructor stub } //该方法会在一个单独的线程中执行,来完成工作任务 //任务结束后,该service会自动停止 @Override protected void onHandleIntent(Intent intent) { // TODO Auto-generated method stub for(int i=0;i<10;i++){ System.out.println(Thread.currentThread().getName()+":"+i); 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(); System.out.println("OnDestory"); } }
所有的service需要在清单文件中申明
<service android:name="com.service.service.HelloService"></service>
<service android:name="com.service.service.HelloIntentService"></service>
使用onBind方式
package com.service.service; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; /** * 实现一个绑定服务 * * */ public class MyService extends Service{ private PersonImpl personImpl; @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); System.out.println("MyServiceOnCreate()"); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub System.out.println("MyServiceOnBind()"); personImpl=new PersonImpl(); return personImpl; } @Override public boolean onUnbind(Intent intent) { // TODO Auto-generated method stub System.out.println("MyServiceOnUnBind()"); return super.onUnbind(intent); } }
自定义AIDL
IStudent.aidl
package com.service.service; import com.service.service.Student; interface IStudent { void setStudnet(String name,String sex); Student getStudent(); }
Student.aidl
parcelable Student;
Student
package com.service.service; import android.os.Parcel; import android.os.Parcelable; public class Student implements Parcelable{ private String name; private String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public int describeContents() { // TODO Auto-generated method stub return 0; } @Override public void writeToParcel(Parcel dest, int flags) { // TODO Auto-generated method stub dest.writeString("name"); dest.writeString("sex"); } public static final Parcelable.Creator<Student> CREATOR = new Parcelable.Creator<Student>() { public Student createFromParcel(Parcel in) { Student student=new Student(); student.setName(in.readString()); student.setSex(in.readString()); return student; } public Student[] newArray(int size) { return new Student[size]; } }; }
StudentImpl
package com.service.service; import android.os.RemoteException; /** * 业务对象的实现 * */ public class StudentImpl extends IStudent.Stub{ private Student student; public StudentImpl(){ student=new Student(); } @Override public void setStudnet(String name, String sex) throws RemoteException { // TODO Auto-generated method stub this.student.setName(name);; this.student.setSex(sex); } @Override public Student getStudent() throws RemoteException { // TODO Auto-generated method stub return student; } }
StudentService
package com.service.service; import android.app.Service; import android.content.Intent; import android.os.IBinder; public class StudentService extends Service{ private StudentImpl studentImpl; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub studentImpl=new StudentImpl(); return studentImpl; } }
使用Messenge
MessageService
package com.service.service; import android.app.Service; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.widget.Toast; public class MessageService extends Service{ static final int MSG_HELLO=0x1; private Handler handler=new Handler(){ public void handleMessage(android.os.Message msg) { switch (msg.what) { case MSG_HELLO: Toast.makeText(MessageService.this, "hello", Toast.LENGTH_SHORT).show(); break; default: break; } }; }; private Messenger messenger=new Messenger(handler); @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return messenger.getBinder(); } }
MessageActivity
package com.service.service; import com.example.service.R; 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.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.view.View; /** * 使用Messenger实现IPC, * 1.Messenger是线程安全的,在service中创建一个Messenger对象并绑定一个handle * 2.在onBind方法中返回messenger对象,通过messenger的getIBinder方法返回一个IBinder对象 * 3.在调用的组件中,ServiceConnection的onServiceConnection时间中,根据IBinder对象来创建一个Messenger对象 * 这样两个Messenger对象就同事绑定到一个IBinder对象上,从而可以底线通信, * 在调用组件中方法种使用Messenger的send方法来发送消息到service的Messenger对象中 * */ public class MessageActivity extends Activity{ private Messenger messenger; private boolean mBound=false; private ServiceConnection conn=new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub if(mBound){ mBound=false; } } @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub messenger=new Messenger(service); mBound=true; } }; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.message_main); } public void useMessenger(View view){ Message message=Message.obtain(); message.what=MessageService.MSG_HELLO; try { messenger.send(message); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); Intent intent=new Intent(this,MessageService.class); bindService(intent, conn, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); if(mBound){ unbindService(conn); mBound=false; } } }
清单文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.service" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.service.service.MessageActivity" 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="com.service.service.HelloService"></service> <service android:name="com.service.service.HelloIntentService"></service> <service android:name="com.service.service.MyService" android:process=":remote"></service> <service android:name="com.service.service.StudentService"></service> <service android:name="com.service.service.MessageService"></service> </application> </manifest> <!-- android:process=":remote"设置运行在自己的进程中 -->
时间: 2024-12-17 21:11:41