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();
}
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"设置运行在自己的进程中 -->
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。