实践

占位式插件化框架—动态广播的使用

2020-01-05  本文已影响0人  migill

如果没有看过占位式插件化框架—Activity通信的请先看这篇文章,因为这篇文章是在它的实例的基础上写的。
思考:插件p.apk中的PluginActivity怎么动态注册广播和发送广播?

如果看占位式插件化框架—Activity通信占位式插件化框架—Service通信这两篇文章,实现这个是很简单的。

\color{red}{在标准stander模块中增加ReceiverInterface接口}\

public interface ReceiverInterface {
    void onReceive(Context context, Intent intent);
}

\color{red}{在plugin\_package模块中增加的类和方法}\

public class MyReceiver extends BroadcastReceiver implements ReceiverInterface {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "我是插件里面的广播接收者,我收到了广播", Toast.LENGTH_LONG).show();
        Log.e("migill", "MyReceiver onReceive 接收到广播 ");
    }
}
public class BaseActivity extends Activity implements ActivityInterface {
    .......
    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        Log.e("migill", "BaseActivity registerReceiver receiver : " + receiver.getClass().getName());
        return appActivity.registerReceiver(receiver, filter);
    }

    @Override
    public void sendBroadcast(Intent intent) {
        Log.e("migill", "BaseActivity sendBroadcast action :" + intent.getAction());
        appActivity.sendBroadcast(intent);
    }
    }
}

在BaseActivity中增加注册广播和发送广播的方法。registerReceiver()和sendBroadcast()两个方法都是调用宿主中的方法。

public class PluginActivity extends BaseActivity {
    private final String ACTION = "com.migill.plugin_package.ACTION";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_plugin);//执行的是BaseActivity中的setContentView方法
        Log.e("migill", "我是插件PluginActivity");
        .......
        findViewById(R.id.bt_register_receiver).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                IntentFilter intentFilter = new IntentFilter();
                intentFilter.addAction(ACTION);
                registerReceiver(new MyReceiver(), intentFilter);
            }
        });

        findViewById(R.id.bt_send_receiver).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction(ACTION);
                sendBroadcast(intent);
            }
        });
    }
}

点击注册广播的按钮,调用的是BaseActivity中的registerReceiver()。
点击发送广播的按钮,调用的是BaseActivity中的sendBroadcast()。
编译apk,重命名为p.apk,并放入 /storage/emulated/0/Android/data/com.migill.pluginproject/files/这个目录下。

\color{red}{在宿主apk中加入代理广播接收者的类和需要添加的注册广播/发送广播的方法}\

public class ProxyActivity extends Activity {
......
    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        String pluginMyReceiverClassName = receiver.getClass().getName();
        Log.e("migill", "ProxyActivity registerReceiver pluginMyReceiverClassName : " + pluginMyReceiverClassName);
        return super.registerReceiver(new ProxyReceiver(pluginMyReceiverClassName), filter);
    }

    @Override
    public void sendBroadcast(Intent intent) {
        Log.e("migill", "ProxyActivity sendBroadcast action : " + intent.getAction());
        super.sendBroadcast(intent);
    }
}

这两个方法都是动态注册广播和发送广播的方法。实际上这里注册的是代理的广播接收者ProxyReceiver。

public class ProxyReceiver extends BroadcastReceiver {

    private String pluginMyReceiverClassName;

    public ProxyReceiver(String pluginMyReceiverClassName) {
        this.pluginMyReceiverClassName = pluginMyReceiverClassName;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("migill", "ProxyReceiver onReceive 接收到了广播");
        //加载插件里面的MyReceiver
        try {
            Class mMyRecevierClass = PluginManager.getInstance(context).getClassLoader().loadClass(pluginMyReceiverClassName);
            Object mMyReceiver = mMyRecevierClass.newInstance();
            ReceiverInterface receiverInterface = (ReceiverInterface) mMyReceiver;
            receiverInterface.onReceive(context, intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

接收到广播的时候会走onReceive()方法,它就会根据全类名实例化对象,并调用receiverInterface.onReceive()。


上一篇下一篇

猜你喜欢

热点阅读