Android手写占位式插件化框架之Activity通信、Service通信和BroadcastReceiver通信(二)

简介: Android手写占位式插件化框架之Activity通信、Service通信和BroadcastReceiver通信

三、插件包plugin_package中,首先实现BaseActivity类

/**
 * @Author: ly
 * @Date: 2023/7/14
 * @Description: 插件包中Activity基础类, 拿到宿主的上下文环境
 */
public class BaseActivity extends Activity implements ActivityInterface {
    private static final String TAG = "BaseActivity";
    /**
     * 宿主的环境
     */
    public Activity appActivity;
    @Override
    public void insertAppContext(Activity appActivity) {
        this.appActivity = appActivity;
    }
    @SuppressLint("MissingSuperCall")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        String appName = savedInstanceState.getString("appName");
        Log.i(TAG, "appName: " + appName);
    }
    @SuppressLint("MissingSuperCall")
    @Override
    public void onStart() {
    }
    @SuppressLint("MissingSuperCall")
    @Override
    public void onResume() {
    }
    @SuppressLint("MissingSuperCall")
    @Override
    public void onPause() {
    }
    @SuppressLint("MissingSuperCall")
    @Override
    public void onStop() {
    }
    @SuppressLint("MissingSuperCall")
    @Override
    public void onDestroy() {
    }
    public void setContentView(int resId) {
        appActivity.setContentView(resId);
    }
    public View findViewById(int id) {
        return appActivity.findViewById(id);
    }
    /**
     * 启动插件包内的第二个Activity:TestActivity
     *
     * @param intent 意图数据
     */
    public void startActivity(Intent intent) {
        Intent newIntent = new Intent();
        newIntent.putExtra("className", intent.getComponent().getClassName());
        appActivity.startActivity(newIntent);
    }
    public ComponentName startService(Intent serviceIntent) {
        Intent newIntent = new Intent();
        //serviceIntent.getComponent().getClassName() 这里拿到的是TestService的全类名
        newIntent.putExtra("className", serviceIntent.getComponent().getClassName());
        return appActivity.startService(newIntent);
    }
    /**
     * 注册广播
     *
     * @param receiver
     * @param intentFilter
     * @return
     */
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter intentFilter) {
        return appActivity.registerReceiver(receiver, intentFilter);
    }
    /**
     * 发送广播
     *
     * @param intent
     */
    public void sendBroadcast(Intent intent) {
        appActivity.sendBroadcast(intent);
    }
}

3.2 插件包中首页PluginActivity,代码如下

/**
 * 首先加载该页面PluginActivity
 */
public class PluginActivity extends BaseActivity {
    private static final String TAG = "PluginActivity";
    private static final String ACTION = "com.example.plugin_package.ACTION";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String appName = savedInstanceState.getString("appName");
        Log.i(TAG, "appName: " + appName);
        setContentView(R.layout.activity_plugin);
        Toast.makeText(appActivity, "我是插件", Toast.LENGTH_SHORT).show();
        //点击按钮跳转到TestActivity
        findViewById(R.id.btn_start_activity).setOnClickListener(v -> {
            startActivity(new Intent(appActivity, TestActivity.class));
        });
        //点击按钮跳转到TestService
        findViewById(R.id.btn_start_service).setOnClickListener(v -> {
            startService(new Intent(appActivity, TestService.class));
        });
        //插件内部注册插件的广播接收者
        findViewById(R.id.btn_register_receiver).setOnClickListener(v -> {
            IntentFilter filter = new IntentFilter();
            filter.addAction(ACTION);
            registerReceiver(new MyReceiver(), filter);
        });
        //插件内部发送插件的广播接收者
        findViewById(R.id.btn_send_receiver).setOnClickListener(v -> {
            Intent intent = new Intent();
            intent.setAction(ACTION);
            sendBroadcast(intent);
        });
    }
}

3.3 点击PluginActivity中的按钮,可以跳转到TestActivity,代码如下:

public class TestActivity extends BaseActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
    }
}

3.4、BaseService类

/**
 * @Author: ly
 * @Date: 2023/7/15
 * @Description: 基础Service继承标准库中ServiceInterface接口
 */
public class BaseService extends Service implements ServiceInterface {
    private Service appService;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void insertAppContext(Service appService) {
        this.appService = appService;
    }
    @Override
    public void onCreate() {
    }
    @SuppressLint("WrongConstant")
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return 0;
    }
    @Override
    public void onDestroy() {
    }
}

3.5、TestService类

/**
 * @Author: ly
 * @Date: 2023/7/15
 * @Description: 插件中的Service
 */
public class TestService extends BaseService {
    private static final String TAG = "TestService";
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //开启子线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        Log.i(TAG, "插件里面的服务正在执行中!");
                    }
                }
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

3.6、插件中的广播接收者MyReceiver

/**
 * @Author: ly
 * @Date: 2023/7/15
 * @Description: 插件中的广播接收者
 */
public class MyReceiver extends BroadcastReceiver implements ReceiverInterface {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "我是插件里面的广播接收者,我收到了广播!", Toast.LENGTH_SHORT).show();
    }
}

一、这个是宿主APP启动插件Activity流程:

二、这个是插件中启动Activity的流程如下图:

三、下面是插件中启动Service的流程图如下:

四、插件中启动BroadcastReceiver,这是在插件中动态注册广播接收者,并在插件内部发送广播。

五、宿主app中获取插件包中静态注册的广播接收者StaticeReceiver,并在宿主app中发送静态广播请看这篇文章

Android手写占位式插件化框架之apk解析原理系统源码分析

六、编写代码后,将plugin_package包手动放到宿主app的私有目录下,便可以正常运行,在公司项目中会将插件包放到服务器用户使用某个功能模块的时候,会下载到本地。

七、具体问题思考

1、为什么在插件中不能使用this?

因为插件是没有在手机上安装的,是无法拥有组件环境的。

2、为什么要有代理的Activity?

由于插件中的Activity并不是一个能够运行的组件,所以需要代理的Activity去代替插件中的Activity(例如Activity进出栈)

3、这种插件化,在写插件开发的时候,有什么要注意的事项?

所有关于操作组件环境的地方,都必须使用宿主的环境。

目录
相关文章
|
4天前
|
Android开发
Android JNI与CAN通信遇到的问题总结
Android JNI与CAN通信遇到的问题总结
26 1
|
2月前
|
设计模式 Android开发
[Android 四大组件] --- BroadcastReceiver
[Android 四大组件] --- BroadcastReceiver
33 0
|
3月前
|
Android开发 开发者
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
44 1
|
3月前
|
数据库 Android开发 开发者
Android基础知识:请解释Activity的生命周期。
Android基础知识:请解释Activity的生命周期。
45 2
|
2月前
|
Android开发
[Android 四大组件] --- Activity
[Android 四大组件] --- Activity
22 1
|
3月前
|
Android开发
Android基础知识:什么是Fragment?与Activity的区别是什么?
Android基础知识:什么是Fragment?与Activity的区别是什么?
293 54
|
4月前
|
缓存 JSON Android开发
[Android]网络框架之OkHttp(详细)(kotlin)
[Android]网络框架之OkHttp(详细)(kotlin)
157 0
|
4月前
|
Android开发 Kotlin
android开发,使用kotlin学习BroadcastReceiver
android开发,使用kotlin学习BroadcastReceiver
69 0
|
4月前
|
XML Java Android开发
Android Studio App开发之利用图片加载框架Glide实现刷新验证码功能(附源码 简单易懂)
Android Studio App开发之利用图片加载框架Glide实现刷新验证码功能(附源码 简单易懂)
34 0