优秀的编程知识分享平台

网站首页 > 技术文章 正文

安卓模块化之路由解耦方案(android路由)

nanyue 2024-08-22 17:33:36 技术文章 5 ℃

一、什么叫做路由?

路由是指:路由器从一个接口上收到数据包,根据数据路由包的目的地址进行定向并转发到另一个接口的过程。

路由概念理解

二、几个概念

广域路由:负责查找目标,精准传递事件

局域路由:负责传递本地的事件到广域路由

本地连接服务:负责连接到广域路由

广域连接服务:负责连接到局域路由

三、需要解决什么问题

四、不完善的地方

1、不支持模块间的回调

2、不支持注解

五、支持的主要功能

1、新增模块间的回调

2、新增注解支持

六、使用方式

Application的配置方式

/**

* RouterAPP

* author yangshun

* email yangshun@lizhi.fm

* created 201709 17:59

**/

public class MyApplication extends RouterApplication {

@Override

public void onCreate() {

super.onCreate();

BlockCanary.install(this, new AppBlockCanaryContext()).start();

}

/**

* 每增加一个进程,必须有对应的一个的连接服务(第一步回调)

*/

@Override

public void initializeAllProcessRouter() {

WideRouter.registerLocalRouter("com.idba.routerapp", MainRouterConnectService.class);

WideRouter.registerLocalRouter("com.idba.routerapp:memory", BigMemoryConnenctService.class);

WideRouter.registerLocalRouter("com.idba.routerapp:music", MusicConnectService.class);

}

/**

* 每个模块,或者一个模块存在两个进程,就需要定义一个Logic类(第二步回调)

*/

@Override

protected void initializeLogic() {

registerApplicationLogic("com.idba.routerapp", 999, AppApplicationLogic.class);

registerApplicationLogic("com.idba.routerapp", 999, MusicApplicationLogic.class);

registerApplicationLogic("com.idba.routerapp:music", 999, MusicApplicationLogic.class);

registerApplicationLogic("com.idba.routerapp", 998, PicApplicationLogic.class);

registerApplicationLogic("com.idba.routerapp:memory", 998, MemoryApplicationLogic.class);

}

/**

* 添加需要自启的进程,以及连接服务,保证后续的性能(第三步回调)

*/

@Override

protected void addBackGroundStartProcess() {

addProcess("com.idba.routerapp:memory", BigMemoryConnenctService.class);

addProcess("com.idba.routerapp:music", MusicConnectService.class);

}

@Override

public boolean needMultipleProcess() {

return true;

}

}

模块间的回调方式-发送端

方法1:

/**

* 将消息回调给指定的Module接收

*

* @param toModuleCallback 指定接收消息module的callback

* @param fromModule 消息来自哪个module

* @param eventCode 消息的EventCode

* @param boo 未定义含义

* @param msg message

* @param bundle bundle 发送的大对象包裹

* @return callback是否发送成功

*/

public synchronized boolean sendEventCallback(String toModuleCallback, String fromModule, String eventCode, boolean boo, String msg, Bundle bundle)

方法2:

/**

* 发送消息,默认所有module能够接收此消息

*

* @param fromModule 消息来自哪个module

* @param eventCode 消息的EventCode

* @param boo 未定义含义

* @param msg message

* @param bundle bundle 发送的大对象包裹

* @return callback是否发送成功

*/

public synchronized boolean sendEventCallbackForAll(String fromModule, String eventCode, boolean boo, String msg, Bundle bundle)

调用方式1 指定模块接受callback回调:

//构造bundle

Bundle bundle = new Bundle();

ArrayList<MusicPlayBean> list = getList(1000);

bundle.putParcelableArrayList("list", list);

//发送callback ,第一个参数 CallBackHelper.CALLBACK_APP 指定APP模块才能接受到此Callback

LocalRouter.getInstance().sendEventCallback(CallBackHelper.CALLBACK_APP, ModuleHelper.Module.MODULE_BIG_MEMORY, ModuleHelper.EventMemory.PARSE_LIST, true, "启动memory页面,独立进程,这个是远程回调方法!", bundle);

调用方式2 全部模块都能接收到callback回调:

//构造Bundle

Bundle bundle = new Bundle();

MusicPlayBean playBean = new MusicPlayBean().setDuration(12 * 60).setSpeed(100).setArtist("古巨基").setName("情歌王").setAuthor(100);

bundle.putParcelable("playBean", playBean);

MemoryBean memoryBean = new MemoryBean().setTotalSize(1024).setRelaySize(450);

bundle.putParcelable("memoryBean", memoryBean);

// sendEventCallbackForAll 这个方法发送的回调,所有模块都能接收到

LocalRouter.getInstance().sendEventCallbackForAll(ModuleHelper.Module.MODULE_BIG_MEMORY, ModuleHelper.EventMemory.PARSE_MULITBEAN, true, "启动memory页面,独立进程,这个是远程回调方法!", bundle);

模块间的回调支持发送以下消息:

基本数据类型:int,String boolean 后面可扩展至 double float long

自定义的大对象:实现Parcelable 接口的对象

List列表

同时发送多个大对象

路由的跳转例子(Activity的启动)

路由的跳转支持注解方式跳转,并且推荐这样使用,简洁方便。

这个例子是Activity的启动,其他更多的路由方式的Action 类似,可以根据自己的需求自定义Action。

1、先定义一个接口服务:

/**

* Router

* author yangshun

* email yangshun@lizhi.fm

* created 2017-10-16 11:20

* describe:

**/

public interface AppRouterService {

/**

* 控制音乐模块的音乐播放,并且传递一个musicId

* @param context

* @param musicId

* @return

*/

@CombinationUri(domain =DomainHelper.DOMAIN_MUSIC,provider = ProviderHelper.PROVIDER_MUSIC,action = ActionHelper.Action_Music.MUSIC_ACTION_PLAY)

String startMusicModulePlay(Context context,@IntentExtrasParam("musicId") String musicId);

/**

* 跳转至图片模块的Activity,以 startActivityForResult 的方式跳转

* (note:暂时仅支持在相同进程中 实现 startActivityForResult 方式跳转)

* @param context

* @param PictureID

* @param requestCode

* @return

*/

@CombinationUri(domain =DomainHelper.DOMAIN_PIC,provider = ProviderHelper.PROVIDER_PIC ,action = ActionHelper.Action_Pic.PIC_ACTION_MAIN)

String startPicModuleActivityForResult(Context context,@IntentExtrasParam("PictureID") String PictureID,@IntentExtrasParam("requestCode") String requestCode);

/**

* 跳转至图片模块的Activity,以 startActivity 的方式跳转

* @param context

* @param PictureID

* @return

*/

@CombinationUri(domain = DomainHelper.DOMAIN_PIC,provider = ProviderHelper.PROVIDER_PIC,action =ActionHelper.Action_Pic.PIC_ACTION_MAIN)

String startPicModuleActivity(Context context,@IntentExtrasParam("PictureID") String PictureID);

/**

* 跳转至 大内存模块,另一个进程 的Activity,以 startActivity 的方式跳转

* @param context

* @param memorySize

* @return

*/

@CombinationUri(domain = DomainHelper.DOMAIN_MEMORY,provider = ProviderHelper.PROVIDER_MEMORY,action = ActionHelper.Action_Memory.MEMORY_ACTION_STARTMAIN)

String startToBigMemory(Context context,@IntentExtrasParam("memorySize") String memorySize);

}

2、在MainActivity中获取这个类的实例

AppRouterService appRouterService = LocalRouter.getInstance().create(AppRouterService.class);

3、调用

// 启动方式1 (存在依赖情况)

// startActivity(new Intent(MainActivity.this, BigMemoryMainActivity.class));

// 启动方式2(传统路由方式)

// startToBigMemory();

// 启动方式3(注解方式,推荐使用)

long start1 = System.currentTimeMillis();

String memory = appRouterService.startToBigMemory(MainActivity.this, "1024");

long time1 = System.currentTimeMillis() - start1;

String text1 = "路由跳转 —> 其他模块的其他进程耗时:" + time1 + "毫秒";

System.out.println(text1);

Toast.makeText(this, text1, Toast.LENGTH_SHORT).show();

Toast.makeText(this, memory, Toast.LENGTH_SHORT).show();

4、在大内存模块,它对应的Action类 的invoke方法

/**

* RouterAPP

* author yangshun

* email yangshun@lizhi.fm

* created 201709 16:03

**/

public class StartBigemoryMainActAction extends RouterAction {

private static final String TAG = "StartBigemoryMainActAct";

@Override

public boolean isAsync(Context context, HashMap<String, String> requestData) {

return false;

}

/**

* 实现这个Action的具体逻辑事件

* @param context

* @param requestData

* @return

*/

@Override

public RouterActionResult invoke(Context context, HashMap<String, String> requestData) {

//从这个 requestData hashMap中获取通过路由传递的参数

String memorySize = requestData.get("memorySize");

if (context instanceof Activity) {

Intent intent = new Intent(context, BigMemoryMainActivity.class);

intent.putExtra("memorySize", memorySize);

context.startActivity(intent);

} else {

Intent intent = new Intent(context, BigMemoryMainActivity.class);

intent.putExtra("memorySize", memorySize);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(intent);

}

// 如果不需要通知,则可以 return null;

return new RouterActionResult.Builder().code(RouterActionResult.CODE_SUCCESS).msg("success").data("跳转成功~").build();

}

5、在 BigMemoryMainActivity 类中,可以通过注解的方式解析

public class BigMemoryMainActivity extends AppCompatActivity {

private static final String TAG = "BigMemoryMainActivity";

private Handler handler = new Handler();

private MemoryRouterService memoryRouterService;

// 获取 memorySize 方式2,注解方式声明注解字段

@InjectParams

String memorySize;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_big_memory_main);

memoryRouterService = LocalRouter.getInstance().create(MemoryRouterService.class);

// 获取 memorySize 方式1:原生api解析

// Bundle extras = getIntent().getExtras();

// if (extras != null) {

// String memorySize = extras.getString("memorySize");

// System.out.println("memorySize = " + memorySize);

// }

// 获取 memorySize 方式2,注解方式

RouterInjector.inject(this);

System.out.println("memorySize = " + memorySize);

Toast.makeText(this, memorySize, Toast.LENGTH_SHORT).show();

}

Tags:

最近发表
标签列表