一个Activity一个线程

只能在主线程更新ui?不存在的,任何一个Activity都可以在子线程中(然并卵,好像没啥卵用)

img1

img2

具体实现

  • 替换ActivityThread.mH.callback从而监听Activity生命周期等一系列对Activity的调用
  • 取出handleMessage(final Message msg)的msg中的binder,每一个binder对应一个Activity,为该binder对象创建一个HandlerThread
  • 在这个handlerThread中调用mH的相关方法

主要代码

/**
 * 测试通过
 * api 18
 * api 19
 * api 21
 * api 24
 * api 26
 * api 28
 */
public class MultiThreadActivity {
    private Map<IBinder, HandlerThread> handlerThreadMap = new HashMap<>();

    private IActivityLifecycleCompact lifecycleCompact;


    public MultiThreadActivity(Context context) {
        if (Build.VERSION.SDK_INT >= 28) {
            lifecycleCompact = new ActivityLifecycleV28Compact(context);
        } else if (Build.VERSION.SDK_INT >= 26) {
            lifecycleCompact = new ActivityLifecycleV26Compact();
        } else if (Build.VERSION.SDK_INT >= 24) {
            lifecycleCompact = new ActivityLifecycleV24Compact();
        } else if (Build.VERSION.SDK_INT >= 21) {
            lifecycleCompact = new ActivityLifecycleV21Compact();
        } else if (Build.VERSION.SDK_INT >= 15) {
            lifecycleCompact = new ActivityLifecycleV15Compact();
        } else {
            lifecycleCompact = new ActivityLifecycleV0Compact();
        }
        try {
            init();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    private void init() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException, InvocationTargetException, IllegalAccessException {

        Class activityThreadClass = Class.forName("android.app.ActivityThread");
        Object activityThread = activityThreadClass.getDeclaredMethod("currentActivityThread").invoke(null);

        final Field mhField = activityThreadClass.getDeclaredField("mH");
        mhField.setAccessible(true);
        final Handler mhHandler = (Handler) mhField.get(activityThread);
        Field callbackField = Handler.class.getDeclaredField("mCallback");
        callbackField.setAccessible(true);
        final Handler.Callback originCallback = (Handler.Callback) callbackField.get(mhHandler);
        callbackField.set(mhHandler, new Handler.Callback() {

            @Override
            public boolean handleMessage(final Message msg) {
                final Message message = new Message();
                message.copyFrom(msg);
                if (Build.VERSION.SDK_INT >= 28) {//android P 生命周期全部走这
                    return deliverAboveApi28(msg, message, mhHandler);
                } else {
                    return deliverBeforeApi28(msg, message, mhHandler);
                }
            }
        });
    }

    private boolean deliverBeforeApi28(Message msg, Message message, Handler mhHandler) {
        final int LAUNCH_ACTIVITY = 100;
        final int PAUSE_ACTIVITY = 101;
        final int PAUSE_ACTIVITY_FINISHING = 102;
        final int STOP_ACTIVITY_HIDE = 104;
        final int RESUME_ACTIVITY = 107;
        final int DESTROY_ACTIVITY = 109;
        final int NEW_INTENT = 112;
        final int RELAUNCH_ACTIVITY = 126;
        final int CONFIGURATION_CHANGED = 118;

        switch (msg.what) {
            case LAUNCH_ACTIVITY:// startActivity--> activity.attach  activity.onCreate  r.activity!=null  activity.onStart  activity.onResume
                IBinder iBinder = lifecycleCompact.onLaunchActivity(msg);

                deliverOnChildThread(message, iBinder, mhHandler);
                return true;
            case RESUME_ACTIVITY://回到activity onRestart onStart onResume
                iBinder = lifecycleCompact.onResumeActivity(msg);
                deliverOnChildThread(message, iBinder, mhHandler);
                return true;
            case PAUSE_ACTIVITY_FINISHING://按返回键 onPause
                iBinder = lifecycleCompact.onPauseActivityFinish(msg);
                deliverOnChildThread(message, iBinder, mhHandler);
                return true;
            case PAUSE_ACTIVITY://开启新页面时,旧页面执行 activity.onPause
                iBinder = lifecycleCompact.onPauseActivity(msg);
                deliverOnChildThread(message, iBinder, mhHandler);
                return true;
            case STOP_ACTIVITY_HIDE://开启新页面时,旧页面执行 activity.onStop
                iBinder = lifecycleCompact.onStopActivityHide(msg);
                deliverOnChildThread(message, iBinder, mhHandler);
                return true;
            case DESTROY_ACTIVITY:// 关闭activity onStop  onDestroy
                iBinder = lifecycleCompact.onDestroyActivity(msg);
                deliverOnChildThread(message, iBinder, mhHandler);
                return true;
            case NEW_INTENT:// TODO: 2018/12/29

                return false;
            case CONFIGURATION_CHANGED:// TODO: 2018/12/29

                return false;
            case RELAUNCH_ACTIVITY:
                iBinder = lifecycleCompact.onReLaunchActivity(msg);
                deliverOnChildThread(message, iBinder, mhHandler);
                return true;
        }
//                if (originCallback != null) {
//                    return originCallback.handleMessage(msg);
//                }
        return false;
    }

    private boolean deliverAboveApi28(Message msg, Message message, Handler mhHandler) {
        final int EXECUTE_TRANSACTION = 159;
        final int ENTER_ANIMATION_COMPLETE = 149;
        final int CONFIGURATION_CHANGED = 118;
        final int DUMP_ACTIVITY = 136;
        final int RELAUNCH_ACTIVITY = 160;
        if (msg.what == EXECUTE_TRANSACTION) {
            IBinder iBinder = lifecycleCompact.onLaunchActivity(msg);
            deliverOnChildThread(message, iBinder, mhHandler);
            return true;
        } else if (msg.what == ENTER_ANIMATION_COMPLETE) {
            deliverOnChildThread(message, (IBinder) message.obj, mhHandler);
            return true;
        }
//      else if (){   // TODO: 2018/12/29
//          final int CONFIGURATION_CHANGED = 118;
//          final int DUMP_ACTIVITY = 136;
//          final int RELAUNCH_ACTIVITY = 160;
//      }
//      if (originCallback != null) {
//          return originCallback.handleMessage(msg);
//      }
        return false;
    }

    private void deliverOnChildThread(final Message message, IBinder iBinder, final Handler mhHandler) {
        HandlerThread handlerThread = handlerThreadMap.get(iBinder);

        if (handlerThread == null) {
            handlerThread = new HandlerThread("");
            handlerThread.start();
            handlerThreadMap.put(iBinder, handlerThread);
        }
        new Handler(handlerThread.getLooper()).post(new Runnable() {
            @Override
            public void run() {
                mhHandler.handleMessage(message);
            }
        });
    }


源码 https://github.com/android-notes/MultiThreadActivity

目前还存在很多问题,仅供研究,切莫用于实际项目开发

Android ,我们可以使用 `preLoad()` 方法来预加载下一个 `Activity` 页面。这个方法会在当前 `Activity` 异步地加载下一个 `Activity` 页面的布局和资源,以提高用户体验。 以下是一个预加载下一个 `Activity` 页面的示例代码: ```java private void preLoadNextActivity() { Intent intent = new Intent(this, NextActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); startActivity(intent); overridePendingTransition(0, 0); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(5000); // 模拟加载时间 } catch (InterruptedException e) { e.printStackTrace(); } // 加载完成后,销毁预加载的 Activity finishActivity(NextActivity.class.hashCode()); } }).start(); } ``` 上面的代码,我们首先创建了一个 `Intent` 对象,用来启动下一个 `Activity` 页面。然后,我们使用 `startActivity()` 方法启动这个 `Activity`,并设置了 `FLAG_ACTIVITY_NO_ANIMATION` 标志位,以避免动画效果。接着,我们使用 `overridePendingTransition()` 方法来去掉当前 `Activity` 的退场动画。这样做可以提高用户体验,使用户感觉当前 `Activity` 顺畅地过渡到了下一个 `Activity`。 接下来,我们在一个线程模拟加载时间,等待 5 秒钟。在等待时间结束后,我们使用 `finishActivity()` 方法销毁预加载的 `Activity`,以释放资源。 最后,我们可以在当前 `Activity` 调用 `preLoadNextActivity()` 方法来预加载下一个 `Activity` 页面。这样,在用户点击跳转按钮时,下一个 `Activity` 页面就能够快速地加载出来,提高用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值