android 状态保持



场景:设备开机后,播放收音机或音乐,如果这个时候关机,或直接拔电重启,则下次启动设备后,恢复播放收音机或音乐,如果启动前音乐在前台,则还需要把音乐恢复到前台,如果启动前是后台,则还是后台播放


思路:

1、音频策略记录在三种状态中记录其当前播放音频的包名和状态,四种状态为:PLAY【记录其播放】、KILL【记录其清楚】、STOP【记录其清除】,通过广播的方式,告知状态管理服务,使其更新SharedPreferences存储的属性mediaPkgName,这个只能告知其是否播放在重启之前,怎么判断当前多媒体音频应用是否在前台,请看第2项

2、通过记录其activity的状态,两种状态Resume和finish,来告知当前启动的应用的包名和下一个应用启动的包名,其实现在activity的管理类ActivityManagerService中

    void reportResumedActivityLocked(ActivityRecord r) {
       
        
     ......
     
        
        int i = mWatchers.beginBroadcast();
        while (i > 0) {
            i--;
            IActivityWatcher w = mWatchers.getBroadcastItem(i);
            if (w != null) {
                try {
                    w.activityResuming(identHash);
                    Intent intent = r.intent;                   
                    w.activityOnResume(r.packageName, r.info.name, intent);
                    if(intent.getCategories() != null || "com.app.package.name".equals(r.info.name)) {
                        w.topActivityResuming(r.packageName, r.info.name, intent);
                    }
                } catch (RemoteException e) {
                }
            }
        }
        mWatchers.finishBroadcast();
    }

    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
     
     ......
                int i = mWatchers.beginBroadcast();
                while (i > 0) {
                    i--;
                    IActivityWatcher w = mWatchers.getBroadcastItem(i);
                    if ( w != null) {
                        try {
                            Intent intent = next.intent;                           
                            w.activityGoingBack(next.packageName, next.info.name, intent);
                        } catch (RemoteException e) {                           
                        }
                    }
                }
                mWatchers.finishBroadcast();
   
     ...... 
    }

其中,需要明白其activity的服务管理类的watcher的使用,需要你在你的状态服务类里面去注册其watcher,当然不再使用的时候别忘了unregisterActivityWatcher

ActivityManagerService.java

    public void registerActivityWatcher(IActivityWatcher watcher) {
        synchronized (this) {
            mWatchers.register(watcher);
        }
    }

    public void unregisterActivityWatcher(IActivityWatcher watcher) {
        synchronized (this) {
            mWatchers.unregister(watcher);
        }
    }

StateManagerService.java


ActivityManagerService.registerActivityWatcher(mWatcher);

此mWatcher是aidl的一个实现类需需要你去实现其相应的接口方法,主要用到下面两个函数

    public void activityOnResume(String pkgName, String activityName,  Intent intent){
 
    }

    public void activityGoingBack(String pkgName, String activityName, Intent intent) {   
   
    }

通过上面两个回调函数里面的参数pkgName来判断当前是否为音乐或收音机来记录其状态到SharedPreferences中,下次重启后,再取了看下,最后一次的包名是否为音乐或收音机的,如果是则进行启动该多媒体应用

3、音乐应用里面很多模块,比如SD卡音乐、网络音乐、我的收藏、等等,那么恢复到具体哪个模块,就需要音乐应用自己去记录其最后一次状态了,而这个状态是在其一进去该模块就进行记录的,不能等拔电再记录,那样已经迟了根本不给你记录的机会了

4、我们还需要判断用户是否之前做过恢复出厂设置,当然需要考虑的细节不仅仅这么些,这个需要考虑的细节才是真正的重点,比如我们需要考虑下面一种更可怕的情况,即,如果我们状态保持在开机后需要去启动应用,比如音乐应用,进入到具体某个模块,这个时候可能我们的音频策略服务还没有启动起来,或我们的界面SurfaceFlinger服务也没有起来,而状态保持我们需要直接开机进入那个应用,所以状态服务在system server启动各种服务的时候启动它,这个时候就需要你考虑先后依赖来考虑服务启动顺序

            IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
            if (surfaceFlinger != null) {
                Log.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
                Parcel data = Parcel.obtain();
                data.writeInterfaceToken("android.ui.ISurfaceComposer");
                surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
                                        data, null, 0);
                data.recycle();
                bCallEnableScreenFlag = true;
            }

你还要甚至保证已经是你需要的横屏?

setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
                        mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);

上面基本上已经说明了其流程概要,在项目开发中,你会发现不少小细节,行了,就说到这吧,也希望有学习的兄弟能提出更好的方案






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值