占位式插件化框架—动态广播的使用
2020-01-05 本文已影响0人
migill
如果没有看过占位式插件化框架—Activity通信的请先看这篇文章,因为这篇文章是在它的实例的基础上写的。
思考:插件p.apk中的PluginActivity怎么动态注册广播和发送广播?
如果看占位式插件化框架—Activity通信和占位式插件化框架—Service通信这两篇文章,实现这个是很简单的。
public interface ReceiverInterface {
void onReceive(Context context, Intent intent);
}
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/这个目录下。
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()。