异步处理(Handler&Message&Looper&MessageQueuen)解析

本文深入解析了Android中Looper、Handler及MessageQueue的工作原理,详细介绍了它们之间的交互过程,包括Looper.prepare()、Handler构造方法以及Looper.loop()的具体实现,强调了一个线程只对应一个Looper和MessageQueue的事实。

-----------------------------------------------------------------------------------------------------------

1.
Looper.prepare();
创建Looper对象,同时MessageQueue也会被创建,与当前线程建立对应关系
2.
Hander handler = new Handler();
在Handler的构造方法中会获取当前线程对应的Looper对象和Looper对象中的消息队列(MessageQueue),也就是第一步创建的内容,同时重写handleMessage方法
3.
Loop.loop()
获取第一步创建的Looper对象和消息队列,和第二步是一样的对象,建立for循环从消息队列中取Message,调用Message.target.dispatchMessage(msg)(Message.target是Handler对象)
最终进入第二步handler对象重写的handleMessage方法中

handler.post(runnable)
handler.sendMessage(message)
就是将handler赋值给message的target变量,并将message加入消息队列

一个线程只对应一个Looper,一个Looper只对应一个MessageQueue,一个MessageQueue对应多个Message,一个Message对应一个Handler
所以一个线程可以对应多个Handler
--------------------------------------------------------------------------------------------------------------

private Handler mHandler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        LogUtils.d(TAG,"handleMessage,msg="+msg.what);
        switch (msg.what){
            case MSG_DO_MOUNTED:
                doOnMounted((String)msg.obj);
                break;
            case MSG_DO_EJECTED:
                doOnEjected((String)msg.obj);
                break;
            case MSG_DO_UNMOUNTED:
                doOnUnMounted((StorageVolume)msg.obj);
                break;
            case MSG_DO_SDSWAP:
                doOnSdSwap();
                break;
            default:
                break;
        }
    }
};
private void doPrepareForMount(String mountPoint){
    LogUtils.i(TAG,"doPrepareForMount,mountPoint="+mountPoint);
    if((mCurrentPath+MountPointManager.SEPARATOR).startsWith(mountPoint
    +MountPointManager.SEPARATOR)
            ||mMountPointManager.isRootPath(mCurrentPath)){
        LogUtils.d(TAG,"pre-onMounted");
        if(mService!=null&& mService.isBusy(this.getClass().getName())){
            mService.cancel(this.getClass().getName());
        }
    }
    mMountPointManager.init(getApplicationContext());
}

@Override
public void onMounted(String mountPoint) {//这个应该是在非UI(主)线程中进行的
    LogUtils.i(TAG,"onMounted,mountPoint="+mountPoint);
    Message.obtain(mHandler,MSG_DO_MOUNTED,mountPoint).sendToTarget();
}

private void doOnMounted(String mountPoint){
    LogUtils.i(TAG,"doOnMounted,mountPoint="+mountPoint);
    doPrepareForMount(mountPoint);
    if(mMountPointManager.isRootPath(mCurrentPath)){
        LogUtils.d(TAG,"doOnMounted,mCurrentPath is root path:"+mCurrentPath);
        showDirectoryContent(mCurrentPath);
    }
}

@Override
public void onUnMounted(StorageVolume volume) {
    LogUtils.i(TAG,"onUnMounted,unMountPoint:"+volume.getPath());
    Message.obtain(mHandler,MSG_DO_UNMOUNTED,volume).sendToTarget();
}

@Override
public void onEjected(String unMountPoint) {
    LogUtils.i(TAG,"onUnMounted,unMountPoint:"+unMountPoint);
    Message.obtain(mHandler,MSG_DO_EJECTED,unMountPoint).sendToTarget();
}

@Override
public void onSdSwap() {
    LogUtils.i(TAG,"onSdSwap...");
    Message.obtain(mHandler,MSG_DO_SDSWAP).sendToTarget();
}

private void doOnSdSwap(){
    mMountPointManager.init(getApplicationContext());
    backToRootPath();
}

private void doOnEjected(String unMountPoint){
    if((mCurrentPath+MountPointManager.SEPARATOR).startsWith(unMountPoint
    +MountPointManager.SEPARATOR)
            || mMountPointManager.isRootPath(mCurrentPath)
            || mMountPointManager.isPrimaryVolume(unMountPoint)){
        LogUtils.d(TAG,"onEjected,Current Path="+mCurrentPath);
        if(mService!=null && mService.isBusy(this.getClass().getName())){
            mService.cancel(this.getClass().getName());
        }
    }
}

private void doOnUnMounted(StorageVolume volume){
    String unMountPoint=volume.getPath();
    if(mFileInfoManager!=null){
        int pasteCnt=mFileInfoManager.getPasteCount();
        LogUtils.i(TAG,"doOnUnmounted,unMountPoint:"+unMountPoint+",pasteCnt="
        +pasteCnt);

        if(pasteCnt>0){
            FileInfo fileInfo=mFileInfoManager.getPasteList().get(0);
            if(fileInfo.getFileAbsolutePath().startsWith(
                    unMountPoint+MountPointManager.SEPARATOR)){
                LogUtils.i(TAG,"doOnUnmounted,clear paste list.");
                mFileInfoManager.clearPasteList();
                invalidateOptionsMenu();
            }
        }
    }
    if((mCurrentPath+MountPointManager.SEPARATOR).startsWith(unMountPoint
    +MountPointManager.SEPARATOR)
            || mMountPointManager.isRootPath(mCurrentPath)){
        LogUtils.d(TAG,"onUnmounted,Current Path="+mCurrentPath);
        if(mService!=null && mService.isBusy(this.getClass().getName())){
            mService.cancel(this.getClass().getName());
        }
        showToastForUnmount(volume);

        DialogFragment listFragment=(DialogFragment)getFragmentManager().findFragmentByTag(
                ListListener.LIST_DIALOG_TAG);
        if(listFragment!=null){
            LogUtils.d(TAG,"onUnmounted,listFragment dismiss.");
            listFragment.dismissAllowingStateLoss();
        }

        AlertDialogFragment.EditTextDialogFragment createFolderDialogFragment=
                (AlertDialogFragment.EditTextDialogFragment)getFragmentManager()
                .findFragmentByTag(CREATE_FOLDER_DIALOG_TAG);
        if(createFolderDialogFragment!=null){
            LogUtils.d(TAG,"onUnmounted,createFolderDialogFragment dismiss.");
            createFolderDialogFragment.dismissAllowingStateLoss();
        }
        backToRootPath();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值