android 组件化开发
android 组件化开发
背景
随着应用的体积变大,业务多元化,传统 mvp、mvvm 开发模式很难满足项目发展,各模块耦合度高,团队分工不明确。因此,组件化开发思想诞生
概念
- 什么是组件:我所理解组件是对一段功能逻辑或业务模块逻辑封装,这段逻辑不依赖其他组件是可以独立运行。例如:android 里面的Activiy 组件,Activity就是对窗体的启动、暂停、销毁的管理封装,对于外部的调用,不要知道内部实现细节,只要知道外部接口
- 组件化开发设计:
组价间通信
每个组件都是可以独立运行,可调式,思考,要达到这一点,组件与组件间不存在直接依赖,单独调试的时候编译器是通不过的,无直接依赖,如何实现组件间通信呢,组件间不直接访问,通过中间基础common组件间接访问,common就是中间路由中转,代码我们如何实现呢,我们使用阿里开源框架实现我们的想法,
- 组件间数据跳转:
// An highlighted block
public class MainActivity extends AppCompatActivity {
private Button mbtnStart;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mbtnStart=findViewById(R.id.btn_start_sub);
mbtnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ARouter.getInstance().build("/sub/SubActiivty").navigation();
}
});
}
@Route(path = "/sub/SubActiivty")
public class SubActiivty extends AppCompatActivity {
}
- 组件间数据交换:
例如:用户信息访问,用户信息管理是一个组件,其他组件如何访问用户信息管理组件的个人信息呢
在这里插入图片描述先基础组basemodule件定义路由接口
package com.xuesong.a8500.basemodule.router.provider;
import com.alibaba.android.arouter.facade.template.IProvider;
import com.xuesong.a8500.basemodule.router.bean.IUser;
public interface IUserProvider extends IProvider {
/**
* user 提供
*
* @return
*/
IUser getUserInfo();
/**
* user注入
*
* @param iUser
*/
void setUserInfo(IUser iUser);
}
在用户管理组件里提供用户信息访问服务,
package com.example.usercentermodel;
import android.content.Context;
import android.util.Log;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.xuesong.a8500.basemodule.router.RouterPath;
import com.xuesong.a8500.basemodule.router.bean.IUser;
import com.xuesong.a8500.basemodule.router.provider.IUserProvider;
@Route(path = RouterPath.ROUTER_PATH_USER_SERVICE, name = "用户中心")
public class UserService implements IUserProvider {
@Override
public IUser getUserInfo() {
Log.i("wang", "=======获取 userInfo=======");
return UserState.getInstance().getiUser();
}
@Override
public void setUserInfo(IUser iUser) {
UserState.getInstance().setiUser(iUser);
}
@Override
public void init(Context context) {
}
}
其他组件对用户信息管理组件调用
package com.xuesong.a8500.submodel;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.xuesong.a8500.basemodule.router.RouterPath;
import com.xuesong.a8500.basemodule.router.provider.IUserProvider;
@Route(path = "/sub/SubActiivty")
public class SubActiivty extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IUserProvider iUserProvider = (IUserProvider) ARouter.getInstance().build(RouterPath.ROUTER_PATH_USER_SERVICE).navigation();//访问用户信息
if(iUserProvider!=null){
Log.i("wang","====="+iUserProvider.getUserInfo());
}
}
}
组件application整合
每个业务组件都独立运行,打包成apk都需要一个application ,如果每个module都在自己的module里面去声明自己的application,最后一起集成到app壳肯定是一件痛苦的事情。
- 如何解决多个集成进项目里面多个application问题:common组件是对中间路由管理和分发的,所有的组件数据交互都必要依赖common组件中转,所以我们在common组件声明application,因为每个组件都会间接依赖common组件,如果只在基础组件声明application ,所有组件的application的初始化工作都需要在基础组件申明,最后基础组件的application代码体积越来越大,难以维护。我们可以使用代理application去解决这一问题
- 思路设计:
- 代码实现:
代理接口声明
package com.xuesong.a8500.basemodule;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
import java.io.File;
public interface IAppLicationLike {
void onCreate();
void onTerminate();
void onLowMemory();
void onTrimMemory(int level);
void attachBaseContext(Context base);
Context getBaseContext();
AssetManager getAssets();
Resources getResources();
PackageManager getPackageManager() ;
Looper getMainLooper();
Context getApplicationContext();
Application getApplication();
void setTheme(int resid);
Resources.Theme getTheme();
ClassLoader getClassLoader();
String getPackageName();
ApplicationInfo getApplicationInfo();
File getDataDir();
File getFilesDir();
Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter);
Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags);
Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler);
Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags);
void unregisterReceiver(BroadcastReceiver receiver);
ComponentName startService(Intent service);
}
代理抽象类
package com.xuesong.a8500.basemodule;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import java.io.File;
public class AppLicationLikePoxy implements IAppLicationLike {
private Application application;
protected AppLicationLikePoxy(Application application) {
this.application = application;
}
@Override
public void onCreate() {
}
@Override
public void onTerminate() {
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int level) {
}
@Override
public void attachBaseContext(Context base) {
}
@Override
public Context getBaseContext() {
return application.getBaseContext();
}
@Override
public AssetManager getAssets() {
return application.getAssets();
}
@Override
public Resources getResources() {
return application.getResources();
}
@Override
public PackageManager getPackageManager() {
return application.getPackageManager();
}
@Override
public Looper getMainLooper() {
return application.getMainLooper();
}
@Override
public Context getApplicationContext() {
return application.getApplicationContext();
}
@Override
public Application getApplication() {
return application;
}
@Override
public void setTheme(int resid) {
application.setTheme(resid);
}
@Override
public Resources.Theme getTheme() {
return application.getTheme();
}
@Override
public ClassLoader getClassLoader() {
return application.getClassLoader();
}
@Override
public String getPackageName() {
return application.getPackageName();
}
@Override
public ApplicationInfo getApplicationInfo() {
return application.getApplicationInfo();
}
@Override
public File getDataDir() {
if (Build.VERSION.SDK_INT >= 24) {
return application.getDataDir();
} else {
return null;
}
}
@Override
public File getFilesDir() {
return application.getFilesDir();
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return application.registerReceiver(receiver, filter);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
return null;
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) {
return null;
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) {
return null;
}
@Override
public void unregisterReceiver(BroadcastReceiver receiver) {
application.unregisterReceiver(receiver);
}
@Override
public ComponentName startService(Intent service) {
return application.startService(service);
}
}
代理类
package com.xuesong.a8500.submodel;
import android.app.Application;
import android.content.Context;
import android.util.Log;
import com.xuesong.a8500.basemodule.AppLicationLikeManager;
import com.xuesong.a8500.basemodule.AppLicationLikePoxy;
import com.xuesong.a8500.basemodule.IAppLicationLike;
public class SubAppLicationLike extends AppLicationLikePoxy {
protected SubAppLicationLike(Application application) {
super(application);
}
@Override
public void onCreate() {
super.onCreate();
IAppLicationLike iAppLilcationLike= AppLicationLikeManager.getInstance().getAppLicationLike(AppLicationLikeManager.SUB_APPLICATION_LIKE);
String name=iAppLilcationLike.getResources().getString(R.string.app_name);
Log.i("wang","==name==="+name);
Log.i("wang", "===subLike==oncrete");
Log.i("wang", "===subLike1=="+getResources().getString(R.string.app_name));
}
@Override
public void attachBaseContext(Context base) {
super.attachBaseContext(base);
Log.i("wang", "===subLike==attach");
}
}
ApplicationLikeManager 负责application代理类的管理
package com.xuesong.a8500.basemodule;
import android.app.Application;
import android.content.Context;
import android.util.Log;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
public class AppLicationLikeManager {
public static final String SUB_APPLICATION_LIKE = "com.xuesong.a8500.submodel.SubAppLicationLike";
public static final String MAIN_APPLICATION_LIKE = "com.xuesong.a8500.basemodule.MainAppLicationLike";
HashMap<String, IAppLicationLike> mlikeAppLike = new HashMap();
public static AppLicationLikeManager appLicationLikeManager = null;
private AppLicationLikeManager() {
}
public static AppLicationLikeManager getInstance() {
if (appLicationLikeManager == null) {
appLicationLikeManager = new AppLicationLikeManager();
}
return appLicationLikeManager;
}
public void regitLike(String packageName,Application context) {
try {
Class<?> cls = Class.forName(packageName);
Constructor con = cls.getDeclaredConstructor(Application.class);
con.setAccessible(true);
IAppLicationLike iAppLilcationLike = (IAppLicationLike) con.newInstance(context);
regitLike(packageName, iAppLilcationLike);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private void regitLike(String name, IAppLicationLike iAppLilcationLike) {
mlikeAppLike.put(name, iAppLilcationLike);
}
public void unRegitLike(IAppLicationLike iAppLilcationLike) {
mlikeAppLike.remove(iAppLilcationLike);
}
public void unRegitLike() {
mlikeAppLike.clear();
}
public IAppLicationLike getAppLicationLike(String name) {
return mlikeAppLike.get(name);
}
public void attachBaseContext(Context base) {
for (HashMap.Entry<String, IAppLicationLike> appLilcationLikeEntry : mlikeAppLike.entrySet())
appLilcationLikeEntry.getValue().attachBaseContext(base);
}
public void onCreate() {
Log.i("wang", "====appProxy===" + mlikeAppLike.size());
for (HashMap.Entry<String, IAppLicationLike> appLilcationLikeEntry : mlikeAppLike.entrySet())
appLilcationLikeEntry.getValue().onCreate();
}
public void onTerminate() {
for (HashMap.Entry<String, IAppLicationLike> appLilcationLikeEntry : mlikeAppLike.entrySet())
appLilcationLikeEntry.getValue().onTerminate();
}
public void onLowMemory() {
for (HashMap.Entry<String, IAppLicationLike> appLilcationLikeEntry : mlikeAppLike.entrySet())
appLilcationLikeEntry.getValue().onLowMemory();
}
public void onTrimMemory(int level) {
for (HashMap.Entry<String, IAppLicationLike> appLilcationLikeEntry : mlikeAppLike.entrySet())
appLilcationLikeEntry.getValue().onTrimMemory(level);
}
}
被代理的类注入:
package com.xuesong.a8500.basemodule;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import java.io.File;
public class ComponentAppLication extends Application {
AppLicationLikeManager iAppLilcationLike;
public ComponentAppLication() {
super();
Log.i("wang", "注册 model appLike");
iAppLilcationLike =AppLicationLikeManager.getInstance();
iAppLilcationLike.regitLike(AppLicationLikeManager.SUB_APPLICATION_LIKE,this);
iAppLilcationLike.regitLike(AppLicationLikeManager.MAIN_APPLICATION_LIKE,this);
}
@Override
public void onCreate() {
iAppLilcationLike.onCreate();
/* ServiceLoader<IAppLicationLike> serviceLoader=ServiceLoader.load(IAppLicationLike.class,IAppLicationLike.class.getClassLoader());
Iterator<IAppLicationLike> iterable=serviceLoader.iterator();
if(iterable.hasNext()){
iterable.next().onCreate();
}*/
super.onCreate();
}
@Override
public void onTerminate() {
iAppLilcationLike.onTerminate();
unregitLike();
super.onTerminate();
}
@Override
public void onLowMemory() {
iAppLilcationLike.onLowMemory();
super.onLowMemory();
}
@Override
public void onTrimMemory(int level) {
iAppLilcationLike.onTerminate();
super.onTrimMemory(level);
}
@Override
protected void attachBaseContext(Context base) {
iAppLilcationLike.attachBaseContext(base);
super.attachBaseContext(base);
}
@Override
public Context getBaseContext() {
return super.getBaseContext();
}
@Override
public AssetManager getAssets() {
return super.getAssets();
}
@Override
public Resources getResources() {
return super.getResources();
}
@Override
public PackageManager getPackageManager() {
return super.getPackageManager();
}
@Override
public Looper getMainLooper() {
return super.getMainLooper();
}
@Override
public Context getApplicationContext() {
return super.getApplicationContext();
}
@Override
public void setTheme(int resid) {
super.setTheme(resid);
}
@Override
public Resources.Theme getTheme() {
return super.getTheme();
}
@Override
public ClassLoader getClassLoader() {
return super.getClassLoader();
}
@Override
public String getPackageName() {
return super.getPackageName();
}
@Override
public ApplicationInfo getApplicationInfo() {
return super.getApplicationInfo();
}
@Override
public File getDataDir() {
return super.getDataDir();
}
@Override
public File getFilesDir() {
return super.getFilesDir();
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return super.registerReceiver(receiver, filter);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
return super.registerReceiver(receiver, filter, flags);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) {
return super.registerReceiver(receiver, filter, broadcastPermission, scheduler);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) {
return super.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags);
}
@Override
public void unregisterReceiver(BroadcastReceiver receiver) {
super.unregisterReceiver(receiver);
}
@Override
public ComponentName startService(Intent service) {
return super.startService(service);
}
private void unregitLike() {
iAppLilcationLike.unRegitLike();
}
}