android基础回顾笔记1--四大组件
来源:互联网 发布:mysql 批量update语句 编辑:程序博客网 时间:2024/06/05 10:49
(activity,service,broadcast receiver,content provider)
1.清单文件中注册广播接受者的特点:一旦应用部署到手机上,就相当于在系统注册表中注册了这个广播接受者一样,不论这个
应用是否打开,只要系统发出这个广播,这个接受者就会响应。
2.没有配置activity信息的应用是不会在系统桌面产生图标的。
3.通过代码注册广播接受者:一旦代码所在的进程被杀死了, 广播接受者就失效了.
广播接受者分为两种类型:
4. 广播分为两种类型:有序广播和无序广播
有序的广播:短信到来的广播 电话拨打的广播
-1000~1000 设置广播的优先级
android:priority=”1000”
从高优先级->低优先级 依次传递
abortbroadcast() 方法 可以终止广播事件
无序广播:
没有优先级 任何人 注册广播接受者的人,都可以接收到广播.
没有abortboradcast()方法
5.自定义广播的发送
sendBroadcast(intent); // 发送一条广播
sendOrderedBroadcast(intent, receiverPermission); // 发送一条有序广播
sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras)
如果发送广播的时候 使用的 上面的api发送出去的广播
第三个参数 resultReceiver 指定了广播的接受者.
即便是中间我把广播给终止 abortbroadcast()
resultReceiver 还是会接受到广播事件,但是可以通过在onReceive方法中调用setResultData(null);把广播传过来的数据给改为
空值,这样也能达到停止广播事件的效果。
6.进程和线程之间的关系:
一个进程里面可以有多个线程.
进程如果挂了, 线程就没了.
如果我们激活另外一个应用程序的activity
肯定另外一个应用程序 所在的进程也会被创建出来
为什么要使用 service 是因为service这个组件会长期的在后台运行
一般情况下不会别操作系统回收.广播接受者经常和service搭配使用。
进程的优先级
Foreground process 前台进程
优先级别最高,即便系统内存不足的时候 也不会杀死前台进程
Visible process 可见进程
优先级稍为低一点
Service process 服务进程
存活时间比较长 .
里面的子线程不会回收.
Background process 后台进程
Empty process 空进程
没有任何的组件进程
7.Intent可以激活任意一个组件,包括activity、service、braodcastReceive和contentProvider
8.开启服务的两种方法:
一、开启服务 (startservice) :
服务一旦开启与调用者没有任何的关系 , 调用着的activity 即便是退出了 也不会影响
后台的service的运行. 退出应用并不会关掉应用中的服务,服务仍然会继续存活执行,除非主动关掉-stopService。
在activity里面 不能去调用服务里面的方法 .
生命周期方法:onCreate–onStart–onDestroy,注意;重复调用startService的时候只会执行onStart方法,onCreate方法只会在首次执行一次。
二、服务通过bindservice的方法开启:
首先 如果服务不存在 就会执行 oncreate() ->onbind()方法
一旦服务绑定成功 以后再去执行 bindsercie() 就不会在重新创建 或者绑定服务了();
如果我们现实的调用unbindservice()的方法
首先 on unbind()方法 -> ondestroy() ;
服务只能被解除绑定一次 多次解除绑定服务 程序会出异常.
两种开启服务方法的区别:
开启服务 (startservice) ,服务一旦开启与调用者没有任何的关系 , 调用着的activity 即便是退出了 也不会影响
后台的service的运行. 在activity里面 不能去调用服务里面的方法 .
通过绑定方式开启服务(bindservice),服务跟调用者不求同生 ,但求同死.如果调用者(activity)退出了 那他绑定的服务呢 也会跟着退出.
直接终结服务调用者的activity会出现如下异常:这个异常可以通过在activity的onDestroy方法中主动调用unBind方法接触绑定避免。
03-16 07:45:42.479: ERROR/ActivityThread(8618): Activity cn.itcast.servicelife.DemoActivity
has leaked ServiceConnection cn.itcast.servicelife.DemoActivity
并且,我们可以在activity里面调用服务里面的方法.利用 serviceSonnection 接口 返回一个ibinder对象 ,
拿着ibinder对象获取到服务里面方法的引用(自定义了一个接口信息) ,调用服务里面的方法。
**下面是同一个应用即同一个进程内部通过activity调用所绑定的service中的方法的流程图:
流程总结:
要想访问 一个服务里面的方法 我们需要用到 bindservice();
一 创建一个服务 这个服务里面有一个要被调用的方法.
二 定义一个接口IService , 接口里面的抽象方法 就是去调用service里面的方法
三 定义一个mybinder对象 extends IBinder对象 实现 我们声明的接口IService, 在onbind
方法里面把mybinder返回回去
四 在activity里面 通过bindservice的方法开启服务
五 创建出来一个我们MyConn 实现 ServiceConnection接口 onserviceConnected的方法
这个方法会有一个参数 这个参数就是 MyBinder的对象
六 把mybinder强制类型转化成 IServcie
七 调用IService里面的方法
activity调用所绑定的service中的方法的部分代码如下:
Activity代码:
public class DemoActivity extends Activity implements OnClickListener { Button bt_start; Button bt_stop; Button bt_bind_service; //绑定服务 Button bt_unbind_service; //解除绑定服务 Button bt_call_service; Intent intent ; MyConn conn; IService iService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); bt_start = (Button) this.findViewById(R.id.button1); bt_stop = (Button) this.findViewById(R.id.button2); bt_bind_service = (Button) this.findViewById(R.id.button3); bt_unbind_service = (Button) this.findViewById(R.id.button4); bt_call_service = (Button)this.findViewById(R.id.button5); bt_start.setOnClickListener(this); bt_stop.setOnClickListener(this); bt_bind_service.setOnClickListener(this); bt_unbind_service.setOnClickListener(this); bt_call_service.setOnClickListener(this); intent = new Intent(this,MyService.class); conn = new MyConn(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button1: // 开启服务 startService(intent); break; case R.id.button2: //停止服务 stopService(intent); break; case R.id.button3: // 绑定服务 bindService(intent, conn, Context.BIND_AUTO_CREATE); break; case R.id.button4: //解除绑定服务 unbindService(conn); break; // 绑定开启 case R.id.button5: //调用服务里面的方法 iService.callMethodInService(); break; } } private class MyConn implements ServiceConnection{ //绑定一个服务成功的时候 调用 onServiceConnected @Override public void onServiceConnected(ComponentName name, IBinder service) { iService = (IService) service; } @Override public void onServiceDisconnected(ComponentName name) { } } @Override protected void onDestroy() { unbindService(conn); super.onDestroy(); }}
Service代码:
public class MyService extends Service { @Override public IBinder onBind(Intent intent) { System.out.println("on bind"); return new MyBinder(); } public class MyBinder extends Binder implements IService{ @Override public void callMethodInService() { sayHelloInService(); } } /** * 服务里面的一个方法 */ public void sayHelloInService(){ System.out.println("hello in service"); } @Override public boolean onUnbind(Intent intent) { System.out.println("on unbind"); return super.onUnbind(intent); } @Override public void onCreate() { System.out.println("oncreate"); super.onCreate(); } @Override public void onStart(Intent intent, int startId) { System.out.println("onstart"); super.onStart(intent, startId); } @Override public void onDestroy() { System.out.println("ondestroy"); super.onDestroy(); }}
接口代码:
public interface IService { public void callMethodInService();}
总结:一个应用程序 一个进程里面 定义一个IService 的接口来描述方法 。原理就是借口回调
**而如果我们要调用另外一个进程服务里面的方法,就要通过aidl这种进程间通信的方法(android interface defination language):
流程图:
流程总结:
要想访问一个远程服务里的方法 需要用到aidl
一 创建一个服务 这个服务里面有一个要被调用的方法.
二 定义一个接口IService , 接口里面的抽象方法 就是去调用service里面的方法
把.java的后缀名改成aidl 把接口里面定义的访问权限的修饰符都给删除
三 定义一个mybinder对象 extends IService.Stub, 在onbind
方法里面把mybinder返回回去
四, 在activity里面 通过bindservice的方法开启服务
五 创建出来一个我们MyConn 实现 ServiceConnection接口 onserviceConnected的方法
这个方法会有一个参数 这个参数就是 MyBinder的对象
六 IService = IService.Stub.asInterface(myBinder)
七 调用IService的方法
部分代码如下:
A工程中的Activity代码:
public class DemoActivity extends Activity { IService iService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent = new Intent(); intent.setAction("cn.itcast.remoteservice"); bindService(intent, new MyConn(), BIND_AUTO_CREATE); } public void click(View view){ try { // 调用了远程服务的方法 iService.callMethodInService(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private class MyConn implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { iService = IService.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub } }}
B工程中的service代码:
public class RemoteService extends Service { @Override public IBinder onBind(Intent intent) { return new MyBinder(); } private class MyBinder extends IService.Stub{ @Override public void callMethodInService() throws RemoteException { sayHelloInService(); } } /** * 服务里面的一个方法 */ public void sayHelloInService(){ System.out.println("hello in service"); } @Override public void onCreate() { System.out.println("remote service oncreate"); super.onCreate(); }}
B工程中的aidl文件如下:
interface IService {
void callMethodInService();
}
注意:B工程中的这个aidl文件需要拷贝一份到A工程中相同包目录下,也会自动在gen目录下生成对应的接口。
总结:进程间远程调用service中方法和调用进程内部的service方法的绑定方式和service本身都没有区别,区别在于接口的声明,
内部调用的接口声明就是普通接口;而远程调用的接口需要在服务端去掉public关键字并改为aidl后缀自动生成.java接口,然后
还要把aidl文件拷贝到调用端也自动生成.java接口,除此之外的其他实现方法均大同小异。
进程间调用service中方法的原理:接口回调+序列化
- android基础回顾笔记1--四大组件
- Android回顾之四大组件
- Android四大组件回顾汇总
- Android开发笔记之四大组件琐碎知识回顾总结
- 基础回顾--四大组件之一--Activity
- 基础回顾--四大组件之一--Service
- android基础 四大组件
- android四大组件笔记
- Android笔记--Android四大组件
- Android基础之四大组件
- Android基础之四大组件
- android四大组件BroadCasterReceiver基础
- android四大组件基础总结
- Android 四大组件基础讲义
- Android基础四大组件详解
- Android基础回顾笔记
- Android学习笔记--四大组件
- Android四大组件总结笔记
- category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性
- 0000000
- 确保对象的唯一性——单例模式 (一):动机,概述
- 使用DML语句更改数据
- git初次提交代码到coding出现错误处理方法
- android基础回顾笔记1--四大组件
- iOS开发之小知识
- Ubuntu环境下Redis的安装与JAVA连接测试
- 用3.0实现飞机大战——接入微信分享
- android 图片加载+缓存技术
- [经验技巧] 路由mini安装OpenWRT源的Transmission插件,实现PT下载(需SSH)
- php.ini文件中的include_path设置
- 4.10 VideoView,SurfaceView,MediaPlayer,
- 使用子查询