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.DemoActivityMyConn@44f406f0thatwasoriginallyboundhere031607:45:42.479:ERROR/ActivityThread(8618):android.app.ServiceConnectionLeaked:Activitycn.itcast.servicelife.DemoActivityhasleakedServiceConnectioncn.itcast.servicelife.DemoActivityMyConn@44f406f0 that was originally bound here
并且,我们可以在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中方法的原理:接口回调+序列化

1 0
原创粉丝点击