本地service【Android】
2016-08-06 21:04
441 查看
本地service是一个应用组件,它用来在后台完成一个时间跨度较大的工作且没有关联任何界面
一 服务的特点:
Service在后台运行,不用与用户进行交互
即使用户退出,服务也不会停止
在默认情况下,Service运行在应用程序进程的主线程中,如果需要在Service中处理一些网络连接等耗时的操作,那么应该将这些任务放在分线程中处理,避免阻塞用户界面
二 Service和Activity的区别:
Activity:
Activity对应一个界面
应用退出时,Activity对象就会死亡
应用再次进入,启动的Activity对象是重新创建的
Service
不用任何界面关联
应用退出,Service仍在运行
应用再次进入,启动的Service还是前面运行的Service对象
三 Service和Thread的区别
Service
用来在后台完成一个时间跨度比较大的工作的应用组件
Service的生命周期方法运行在主线程,如果Service想做持续时间比较长的工作,需要启动一个分线程(Thread)
应用退出:Service不会停止
应用再次进入:可以与正在运行的Service进行通信
Thread
用来开启一个分线程的类,做一个长时间的工作
Thread对象的run()在分线程执行
应用退出:Thread不会停止
应用再次进入:不能再控制前面启动的Thread对象
四 Service的分类
Local Service(本地服务)
Service对象与Service的启动者在同个进程中运行,两者的通信时进程内的通信
Remote Service(远程服务)
Service对象与Service的启动者不在同一个进程中进行,这时存在一个进程间通信的问题,Android专门为此设计了AIDL来实现进程间通信
五 Service的使用
1.需要定义一个类继承于Service类
2.在AndroidMainfest.xml中配置Service
六 启动与停止Service
1.方式一: 一般启动与停止
context.startService(Intentintent)
context.stopService(Intentintent)
2.方式二 : 绑定启动与解绑
context.bindService(Intentintent, ServiceConnectionconnection)
context.unbindService(ServiceConnectionconnection)
七 Service的生命周期:
注意:每次startService都会调用Service的onStartCommand()
八 什么时候会用到反射?
1). 功能清单清单文件: 配置应用组件的全类名
2). 布局文件 : 视图标签
3). 显式意图: 指定类的Class对象
4). 调用系统隐藏的API : 使用Class.forName("全类名")调用
哪些情况使用了反射?
1. 指定类名/全类名字符串
2. 使用反射相关API: Class | Method | Field
九 AIDL理解
每个应用程序都运行在自己的独立进程中,并且可以启动另一个应用进程的服务,而且经常需要在不同的进程间传递数据对象。
在Android平台,一个进程不能直接访问另一个进程的内存空间,所以要想对话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界。
AIDL(Android Interface Definition Language)
用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。
如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
八 定义一个AIDL接口,如果需要使用自定义类型的数据对象比如(student)把student进行封装时需要实现Parelable接口,并且需要创建一个跟此对象一样名字的AIDL文件student.aidl
主要通过service和activity通信
第一步:需要在被连接的进程(新建的项目Remote)中封装一个类student需要实现Parelable接口
第三步 需要创建一个aidl如MyService.aidl里面需要使用Student虽然两个在一个包下,但是还得继续导入包删去没用的代码
第四步:需要创建一个Service
以及需要在mainfest中进行注册
需要将第一个项目里的aidl相关的文件复制到这个项目里,注意:包名也必须一样有student student.aidl MyService.aidl
需要在布局文件中写布局文件,主要有一个文本编辑框TextView 3个Button一个用于连接Service一个用于断开连接,最后一个用于显示
在mainActivity的主文件中编写代码
一 服务的特点:
Service在后台运行,不用与用户进行交互
即使用户退出,服务也不会停止
在默认情况下,Service运行在应用程序进程的主线程中,如果需要在Service中处理一些网络连接等耗时的操作,那么应该将这些任务放在分线程中处理,避免阻塞用户界面
二 Service和Activity的区别:
Activity:
Activity对应一个界面
应用退出时,Activity对象就会死亡
应用再次进入,启动的Activity对象是重新创建的
Service
不用任何界面关联
应用退出,Service仍在运行
应用再次进入,启动的Service还是前面运行的Service对象
三 Service和Thread的区别
Service
用来在后台完成一个时间跨度比较大的工作的应用组件
Service的生命周期方法运行在主线程,如果Service想做持续时间比较长的工作,需要启动一个分线程(Thread)
应用退出:Service不会停止
应用再次进入:可以与正在运行的Service进行通信
Thread
用来开启一个分线程的类,做一个长时间的工作
Thread对象的run()在分线程执行
应用退出:Thread不会停止
应用再次进入:不能再控制前面启动的Thread对象
四 Service的分类
Local Service(本地服务)
Service对象与Service的启动者在同个进程中运行,两者的通信时进程内的通信
Remote Service(远程服务)
Service对象与Service的启动者不在同一个进程中进行,这时存在一个进程间通信的问题,Android专门为此设计了AIDL来实现进程间通信
五 Service的使用
1.需要定义一个类继承于Service类
2.在AndroidMainfest.xml中配置Service
<span style="font-size:14px;"><Service android:name=".test.MyService"> <intent-filter> <action android:name="随便一个字符串"/> </intent-filter> </service></span>
六 启动与停止Service
1.方式一: 一般启动与停止
context.startService(Intentintent)
context.stopService(Intentintent)
2.方式二 : 绑定启动与解绑
context.bindService(Intentintent, ServiceConnectionconnection)
context.unbindService(ServiceConnectionconnection)
七 Service的生命周期:
注意:每次startService都会调用Service的onStartCommand()
八 什么时候会用到反射?
1). 功能清单清单文件: 配置应用组件的全类名
2). 布局文件 : 视图标签
3). 显式意图: 指定类的Class对象
4). 调用系统隐藏的API : 使用Class.forName("全类名")调用
哪些情况使用了反射?
1. 指定类名/全类名字符串
2. 使用反射相关API: Class | Method | Field
九 AIDL理解
每个应用程序都运行在自己的独立进程中,并且可以启动另一个应用进程的服务,而且经常需要在不同的进程间传递数据对象。
在Android平台,一个进程不能直接访问另一个进程的内存空间,所以要想对话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界。
AIDL(Android Interface Definition Language)
用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。
如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
八 定义一个AIDL接口,如果需要使用自定义类型的数据对象比如(student)把student进行封装时需要实现Parelable接口,并且需要创建一个跟此对象一样名字的AIDL文件student.aidl
package com.atguigu.service.test.remote; parcelable Student;十 案列-----开启两个进程,一个进程和另一个建立连接后,这个进程在输入框中输入id后,会显示出该学生的相关信息
主要通过service和activity通信
第一步:需要在被连接的进程(新建的项目Remote)中封装一个类student需要实现Parelable接口
package shangguigu.java.remote; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; /** * Created by Dell on 2016/8/6. */ public class Student implements Parcelable{ int id; String name; int age; public Student(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Student() { } @Override public int describeContents() { return 0; } //打包 @Override public void writeToParcel(Parcel dest, int flags) { Log.i("tag","打包"); dest.writeInt(id); dest.writeString(name); dest.writeInt(age); } public static final Parcelable.Creator<Student> CREATOR = new Creator<Student>() { @Override public Student createFromParcel(Parcel source) { Log.i("tag","解包"); //解包 int id = source.readInt(); String name = source.readString(); int age = source.readInt(); return new Student(id,name,age); } //返回指定大小的容器 @Override public Student[] newArray(int size) { return new Student[size]; } }; }第二步需要创建一个student.adil,然后运行一下点击这个键
package shangguigu.java.remote; parcelable Student;
第三步 需要创建一个aidl如MyService.aidl里面需要使用Student虽然两个在一个包下,但是还得继续导入包删去没用的代码
// MyService.aidl package shangguigu.java.remote; import shangguigu.java.remote.Student; // Declare any non-default types here with import statements interface MyService { Student getStudentById(int id); }
第四步:需要创建一个Service
package shangguigu.java.remote; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class RemoteService extends Service { public RemoteService() { } @Override public IBinder onBind(Intent intent) { Log.i("tag","onBind()"); return new StudentService(); } @Override public boolean onUnbind(Intent intent) { Log.i("tag","onUnbind()"); return super.onUnbind(intent); } class StudentService extends MyService.Stub { @Override public Student getStudentById(int id) throws RemoteException { Log.i("tag","service getStudentById()"); return new Student(1,"hahah",10); } } }
以及需要在mainfest中进行注册
<service android:name=".RemoteService"> <intent-filter> <action android:name="fanny"/>//这里的name可以随意写,但是需要记住,以后会需要 </intent-filter> </service>第五步:新建一个新的项目,ServiceClient
需要将第一个项目里的aidl相关的文件复制到这个项目里,注意:包名也必须一样有student student.aidl MyService.aidl
需要在布局文件中写布局文件,主要有一个文本编辑框TextView 3个Button一个用于连接Service一个用于断开连接,最后一个用于显示
在mainActivity的主文件中编写代码
package shangguigu.java.serviceclient; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.Toast; import shangguigu.java.remote.MyService; import shangguigu.java.remote.Student; public class MainActivity extends AppCompatActivity { private EditText et_main; private MyService myService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_main = (EditText) findViewById(R.id.et_main); } public void ConnectService (View v) { Intent intent = new Intent("fanny");//需要连接的Service再mainfest注册时填写的的 if (conn == null) { conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i("tag","onServiceConnected"); myService = MyService.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } }; bindService(intent,conn,BIND_AUTO_CREATE); Toast.makeText(this,"绑定service",Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this,"已经绑定service",Toast.LENGTH_SHORT).show(); } } private ServiceConnection conn; public void SelectStudent (View v) throws RemoteException { if (conn !=null) { if (myService!=null) { int id = Integer.parseInt(et_main.getText().toString()); Log.i("tag",id+""); Student student = myService.getStudentById(id); int _id = student.getId(); if ((id+"").equals(_id+"")) { Toast.makeText(this,student.toString(),Toast.LENGTH_SHORT).show(); }else { Toast.makeText(this,"没有这条信息",Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this,"没有这条信息",Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this,"没有绑定service",Toast.LENGTH_SHORT).show(); } } public void disConnectService (View v) { if (conn != null) { unbindService(conn); conn = null; Toast.makeText(this,"解除绑定",Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this,"没有绑定",Toast.LENGTH_SHORT).show(); } } }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析