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、这种插件化,在写插件开发的时候,有什么要注意的事项?

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

目录
相关文章
|
14天前
|
前端开发 Java 编译器
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
73 36
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
|
3月前
|
开发框架 Dart Android开发
安卓与iOS的跨平台开发:Flutter框架深度解析
在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
|
3月前
|
算法 JavaScript Android开发
|
4月前
|
Java 程序员 API
Android|集成 slf4j + logback 作为日志框架
做个简单改造,统一 Android APP 和 Java 后端项目打印日志的体验。
197 1
|
4月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
113 6
|
Java Android开发 容器
|
4天前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
23 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
14天前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
37 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    Android历史版本与APK文件结构
  • 3
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 6
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 8
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 9
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 10
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 1
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    24
  • 2
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    33
  • 3
    Android历史版本与APK文件结构
    121
  • 4
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 5
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    23
  • 6
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
    57
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    37
  • 8
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    73
  • 9
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    119
  • 10
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
    29