diff --git a/README.md b/README.md index 63a881b..cbd0490 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,319 @@ -# ModularizationArchitecture +## 说明 +从[SpinyTech/ModularizationArchitecture](https://github.com/SpinyTech/ModularizationArchitecture)fork的代码 -ModularizationArchitecture is a routing-based multi-process, component-based architecture on the Android platform: it communicates with different modules and processes by sharing routes without referring to other modules. It is suitable for medium-sized App architecture team collaboration, parallel development, business line decoupling, white-box testing and other scenes. +关于架构说明可以参考 +[Android架构思考(模块化、多进程)](http://blog.spinytech.com/2016/12/28/android_modularization/) -## Getting Start +关于这个fork版本增加了一些新的特性,方便使用,文档地址:[Android组件化之通信(多模块,多进程)](http://www.jianshu.com/p/1fc5f8a2d703) -[开始使用](http://blog.spinytech.com/2017/02/01/ma_get_start_cn/) +## 此fork版本的特性 +### 1 进程间通信数据格式的修改 +请求数据```RouterResquest``` 和返回数据```MaActionResult```分别实现了Parcelable接口,并且分别提供了两个可以自定义的成员变量```requestObject```和```result```,用户在建立请求数据```RouterResquest``` 和返回数据```MaActionResult```可以把自定义的数据传递进去,需要注意的是传递的自定义类型也要实现Parcelable接口。 +``` +//自定义数据 +public class Song implements Parcelable { + public String name; + + public Song(String name) { + this.name = name; + } -[Getting Start](http://blog.spinytech.com/2017/02/03/ma_get_start_en/) + protected Song(Parcel in) { + name = in.readString(); + } -## Download + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(name); + } -Maven: + @Override + public int describeContents() { + return 0; + } -```xml - - com.spinytech.ma - macore - 0.1.2 - pom - + public static final Creator CREATOR = new Creator() { + @Override + public Song createFromParcel(Parcel in) { + return new Song(in); + } + + @Override + public Song[] newArray(int size) { + return new Song[size]; + } + }; +} +``` + +``` +//RouterResquest中设置了自定义类型Song +RouterRequestUtil.obtain(MainActivity.this) + .domain("com.spinytech.maindemo:music") + .provider("music") + .action("play") + .reqeustObject(new Song("see you")) + ) +//MaActionResult中设置自定义类型Song +MaActionResult result = new MaActionResult.Builder() + .code(MaActionResult.CODE_SUCCESS) + .msg("play success") + .result(new Song("lili")) + .build(); +``` +### 2 Provider、Action自动生成 +``` +// 注解Provider,程序运行后将自动注册MusicProvider到com.spinytech.maindemo:music到Router +@Provider(processName = "com.spinytech.maindemo:music") +public class MusicProvider extends MaProvider{ + @Override + protected String getName() { + return "music"; + } +} +// 注解Action,程序运行后将自动注册PlayAction到Provider +@Action(processName = "com.spinytech.maindemo:music", providerName = "music") +public class PlayAction implements MaAction +``` +### 3 Rxjava 的引入 +引入Rxjava之后,修改LocalRoute的route方法,使之返回```Observable```,在调用时可以非常方便地使用Rxjava切换线程: +``` + LocalRouter.getInstance(MaApplication.getMaApplication()) + .rxRoute(MainActivity.this, RouterRequestUtil.obtain(MainActivity.this) + .domain("com.spinytech.maindemo:pic") + .provider("pic") + .action("pic") + .data("is_big", "0")) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.from(ThreadPool.getThreadPoolSingleton())) + .subscribe(new Consumer() { + @Override + public void accept(MaActionResult maActionResult) throws Exception { + Toast.makeText(MainActivity.this, maActionResult.getMsg(), Toast.LENGTH_SHORT).show(); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show(); + } + }); ``` -Gradle: -```groovy -compile 'com.spinytech.ma:macore:0.1.2' +## 使用教程 +项目地址:[https://github.com/wutongke/ModularizationArchitecture](https://github.com/wutongke/ModularizationArchitecture) +### 1 在项目中集成 +1.1 在project的build.gradle中设置dependencies块中支持apt: +``` +classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' +``` +1.2 所有Module中配置apt插件: +``` +apply plugin: 'com.neenbedankt.android-apt' ``` +dependencies块中设置: +``` + apt 'com.github.wutongke.modularization:compile:1.1.1' + compile 'com.github.wutongke.modularization:macore:1.1.1' +``` +### 2 创建自定义Application +2.1 实际Application +我们知道一个app中只有一个Application,所以在主Module中定义Application,然后在其它模块中根据需要实现逻辑Application即可,然后启动时注册逻辑Application,即可管理其生命周期: +``` +public class MyApplication extends MaApplication { -## ProGuard + //多进程中注册各个进程的Router,可以参考第3小节的原理图 + @Override + public void initializeAllProcessRouter() { + WideRouter.registerLocalRouter("com.spinytech.maindemo",MainRouterConnectService.class); + WideRouter.registerLocalRouter("com.spinytech.maindemo:music",MusicRouterConnectService.class); + WideRouter.registerLocalRouter("com.spinytech.maindemo:pic",PicRouterConnectService.class); + } + +//注册各个模块中的逻辑Application,每个模块中可以注册多个逻辑 +//Applicatoin,设置优先级,可以调整模块中多个逻辑Application的 +//调用顺序 + @Override + protected void initializeLogic() { + registerApplicationLogic("com.spinytech.maindemo",999, MainApplicationLogic.class); + registerApplicationLogic("com.spinytech.maindemo",998, WebApplicationLogic.class); + registerApplicationLogic("com.spinytech.maindemo:music",999, MusicApplicationLogic.class); + registerApplicationLogic("com.spinytech.maindemo:pic",999, PicApplicationLogic.class); + } + +//设置是否支持多进程 + @Override + public boolean needMultipleProcess() { + return true; + } +} +``` +当然这个自定义的Application需要注册到manifest文件中。 +使用多进程提供服务的模块需要继承```LocalRouterConnectService```,并且在manifest中注册服务: +``` +public class MusicRouterConnectService extends LocalRouterConnectService { + @Override + public boolean onUnbind(Intent intent) { + Log.e("MRCS","onUnbind"); + return super.onUnbind(intent); + } -If you are using ProGuard you might need to add the following option: + @Override + public void onDestroy() { + super.onDestroy(); + Log.e("MRCS","onDestroy"); + } +} +``` +``` + ``` --dontwarn com.spinytech.** + + +2.2 逻辑Application +逻辑Application通过继承BaseApplicationLogic,实现相应的方法即可被回调。 ``` +public class BaseApplicationLogic { + protected MaApplication mApplication; + public BaseApplicationLogic() { + } + + public void setApplication(@NonNull MaApplication application) { + mApplication = application; + } -## Other + public void onCreate() { + } -[Android架构思考](http://blog.spinytech.com/2016/12/28/android_modularization/) + public void onTerminate() { + } + + public void onLowMemory() { + } + + public void onTrimMemory(int level) { + } + + public void onConfigurationChanged(Configuration newConfig) { + } +} + +//逻辑Application只需要继承BaseApplicationLogic,注册后 +//生命周期会被回调 +public class MainApplicationLogic extends BaseApplicationLogic { + @Override + public void onCreate() { + super.onCreate(); + } +} +``` + +### 3 自定义Provider和Action +定义Provider +``` +@Provider(processName = "com.spinytech.maindemo:music") +public class MusicProvider extends MaProvider{ + @Override + protected String getName() { + return "music"; + } +} +``` +定义Action +``` +@Action(processName = "com.spinytech.maindemo:music", providerName = "music") +public class PlayAction implements MaAction { + + @Override + public boolean isAsync(Context context, RouterRequest requestData) { + return false; + } + + @Override + public MaActionResult invoke(final Context context, final RouterRequest requestData) { + Intent intent = new Intent(context, MusicService.class); + intent.putExtra("command", "play"); + context.startService(intent); + MaActionResult result = new MaActionResult.Builder() + .code(MaActionResult.CODE_SUCCESS) + .msg("play success") + .result(new Song("lili")) + .build(); + Handler handler = new Handler(context.getMainLooper()); + handler.post(new Runnable() { + @Override + public void run() { + if (requestData != null && requestData.getRequestObject() != null) { + Toast.makeText(context, "歌曲名字:" + requestData.getRequestObject().name + "(并不知道)", Toast.LENGTH_SHORT).show(); + } + } + }); + Logger.d("com.spinytech", requestData.getRequestObject().name); + return result; + } + + @Override + public String getName() { + return "play"; + } +} +``` +可以看到定义Provider和Action时分别使用了```@Provider``` 和```@Action``` 注解,这样可以在程序编译时完成自动的注册,不需要手动注册到Router了。 + +其中 ```@Provider```需要设置进程名字,```@Action``` 需要设置进程名字和注册到的Provider名字: +``` +@Provider(processName = "com.spinytech.maindemo:music") +@Action(processName = "com.spinytech.maindemo:music", providerName = "music") +``` +### 4 调用Action +4.1 建立Action调用 +首先需求建立一个请求```RouterRequest```,说明要请求的内容: +``` +RouterRequestUtil.obtain(MainActivity.this) + .domain("com.spinytech.maindemo:music") + .provider("music") + .action("play") + .reqeustObject(new Song("see you")) +``` +可以通过RouterRequestUtil的obtain方法快速建立请求,上例中请求的Action位于"com.spinytech.maindemo:music"进程,Provider是"music",Action是"play",并且传递了相应的参数new Song("see you")。 + +然后使用Rxjava的方式请求Action: +``` +LocalRouter.getInstance(MaApplication.getMaApplication()) + .rxRoute(MainActivity.this, RouterRequestUtil.obtain(MainActivity.this) + .domain("com.spinytech.maindemo:music") + .provider("music") + .action("play") + .reqeustObject(new Song("see you")) + ) + .subscribeOn(Schedulers.from(ThreadPool.getThreadPoolSingleton())) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer() { + @Override + public void accept(MaActionResult maActionResult) throws Exception { + Toast.makeText(MainActivity.this, maActionResult.getMsg(), Toast.LENGTH_SHORT).show(); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show(); + } + }); +``` + +4.2 处理请求 +在music模块中处理刚刚发出的请求,6.3中定义的Provider和Action其实就是处理6.4.1中的请求的,并且返回了```MaActionResult```: +``` +MaActionResult result = new MaActionResult.Builder() + .code(MaActionResult.CODE_SUCCESS) + .msg("play success") + .result(new Song("lili")) + .build(); +``` +## 其它 +注意:在demo的gradle.properties中可以配置Local属性,从而根据需要设置使用本地的library,还是远端的library,更改Local后注意sync。 ## License diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..c419263 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/annotation/.gitignore b/annotation/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/annotation/.gitignore @@ -0,0 +1 @@ +/build diff --git a/annotation/build.gradle b/annotation/build.gradle new file mode 100644 index 0000000..fa139ca --- /dev/null +++ b/annotation/build.gradle @@ -0,0 +1,9 @@ +apply plugin: 'java' + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) +} + +sourceCompatibility = "1.7" +targetCompatibility = "1.7" + diff --git a/annotation/src/main/java/com/linked/annotion/Action.java b/annotation/src/main/java/com/linked/annotion/Action.java new file mode 100644 index 0000000..7399552 --- /dev/null +++ b/annotation/src/main/java/com/linked/annotion/Action.java @@ -0,0 +1,13 @@ +package com.linked.annotion; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Created by erfli on 2/15/17. + */ +@Retention(RetentionPolicy.CLASS) +public @interface Action { + String processName(); + String providerName(); +} diff --git a/annotation/src/main/java/com/linked/annotion/Module.java b/annotation/src/main/java/com/linked/annotion/Module.java new file mode 100644 index 0000000..f71e092 --- /dev/null +++ b/annotation/src/main/java/com/linked/annotion/Module.java @@ -0,0 +1,12 @@ +package com.linked.annotion; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Created by erfli on 2/15/17. + */ +@Retention(RetentionPolicy.CLASS) +public @interface Module { + String name(); +} diff --git a/annotation/src/main/java/com/linked/annotion/Modules.java b/annotation/src/main/java/com/linked/annotion/Modules.java new file mode 100644 index 0000000..cfbc45b --- /dev/null +++ b/annotation/src/main/java/com/linked/annotion/Modules.java @@ -0,0 +1,12 @@ +package com.linked.annotion; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Created by erfli on 2/15/17. + */ +@Retention(RetentionPolicy.CLASS) +public @interface Modules { + String[] modules(); +} diff --git a/annotation/src/main/java/com/linked/annotion/Provider.java b/annotation/src/main/java/com/linked/annotion/Provider.java new file mode 100644 index 0000000..982e1fd --- /dev/null +++ b/annotation/src/main/java/com/linked/annotion/Provider.java @@ -0,0 +1,12 @@ +package com.linked.annotion; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Created by erfli on 2/15/17. + */ +@Retention(RetentionPolicy.CLASS) +public @interface Provider { + String processName(); +} diff --git a/build.gradle b/build.gradle index 3438c38..1a9793b 100644 --- a/build.gradle +++ b/build.gradle @@ -7,6 +7,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:2.2.3' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/compile/.gitignore b/compile/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/compile/.gitignore @@ -0,0 +1 @@ +/build diff --git a/compile/build.gradle b/compile/build.gradle new file mode 100644 index 0000000..95ed890 --- /dev/null +++ b/compile/build.gradle @@ -0,0 +1,11 @@ +apply plugin: 'java' + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + compile 'com.google.auto.service:auto-service:1.0-rc2' + compile 'com.squareup:javapoet:1.6.1' + compile project(':annotation') +} + +sourceCompatibility = "1.7" +targetCompatibility = "1.7" diff --git a/compile/src/main/java/com/compiler/ActionPrecessor.java b/compile/src/main/java/com/compiler/ActionPrecessor.java new file mode 100644 index 0000000..1e774b2 --- /dev/null +++ b/compile/src/main/java/com/compiler/ActionPrecessor.java @@ -0,0 +1,181 @@ +package com.compiler; + +import com.google.auto.service.AutoService; +import com.linked.annotion.Action; +import com.linked.annotion.Module; +import com.linked.annotion.Modules; +import com.linked.annotion.Provider; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; + +@AutoService(Processor.class) +public class ActionPrecessor extends AbstractProcessor { + private Filer filer; + private Messager messager; + + @Override + public Set getSupportedAnnotationTypes() { + Set supportTypes = new HashSet<>(); + supportTypes.add(Action.class.getCanonicalName()); + supportTypes.add(Provider.class.getCanonicalName()); + return supportTypes; + } + + @Override + public synchronized void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + filer = processingEnv.getFiler(); + messager = processingEnv.getMessager(); + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latestSupported(); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (annotations.isEmpty()) { + return false; + } else { + Set provideList = roundEnv.getElementsAnnotatedWith(Provider.class); + Set actionList = roundEnv.getElementsAnnotatedWith(Action.class); + if (provideList.isEmpty() || actionList.isEmpty()) { + return false; + } else { + Set modulesList = roundEnv.getElementsAnnotatedWith(Modules.class); + Set moduleList = roundEnv.getElementsAnnotatedWith(Module.class); + String aptModuleName = "ProviderMappingInit"; + if (!modulesList.isEmpty()) { + Element element = modulesList.iterator().next(); + Modules modules = element.getAnnotation(Modules.class); + generateModulesProviderMappingInit(modules.modules()); + } else if (moduleList.isEmpty()) { + generateDefaultProviderMappingInit(); + } else if (moduleList.size() > 1) { + throw new IllegalArgumentException("one Modules annotation is enough"); + } + + if (!moduleList.isEmpty()) { + Element element = moduleList.iterator().next(); + Module modules = element.getAnnotation(Module.class); + aptModuleName += "_" + modules.name(); + } + generateProviderMapping(aptModuleName, roundEnv); + return true; + } + } + } + + private void generateDefaultProviderMappingInit() { + debug("generateDefaultProviderMappingInit"); + MethodSpec.Builder initBuilder = MethodSpec.methodBuilder("init") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .returns(TypeName.VOID) + .addParameter(HashMap.class, "providerMap") + .addParameter(HashMap.class, "actionMap"); + initBuilder.addStatement("ProviderMappingInit.init(providerMap, actionMap)"); + TypeSpec providerInit = TypeSpec.classBuilder("ProviderInit") + .addModifiers(Modifier.PUBLIC) + .addMethod(initBuilder.build()) + .build(); + try { + JavaFile.builder("com.provider", providerInit) + .build() + .writeTo(filer); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + private void generateModulesProviderMappingInit(String[] modules) { + MethodSpec.Builder initBuilder = MethodSpec.methodBuilder("init") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .returns(TypeName.VOID) + .addParameter(HashMap.class, "providerMap") + .addParameter(HashMap.class, "actionMap") + .addStatement("ProviderMappingInit.init(providerMap, actionMap)"); + for (String moduleName : modules) { + initBuilder.addStatement("ProviderMappingInit_" + moduleName + ".init(providerMap, actionMap)"); + } + TypeSpec providerInit = TypeSpec.classBuilder("ProviderInit") + .addModifiers(Modifier.PUBLIC) + .addMethod(initBuilder.build()) + .build(); + try { + JavaFile.builder("com.provider", providerInit) + .build() + .writeTo(filer); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + private void generateProviderMapping(String fileName, RoundEnvironment roundEnv) { + Set provideList = roundEnv.getElementsAnnotatedWith(Provider.class); + Set actionList = roundEnv.getElementsAnnotatedWith(Action.class); + MethodSpec.Builder initBuilder = MethodSpec.methodBuilder("init") + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .returns(TypeName.VOID) + .addParameter(HashMap.class, "providerMap") + .addParameter(HashMap.class, "actionMap"); + ClassName arrayList = ClassName.get("java.util", "ArrayList"); + for (Element element : provideList) { + if (element.getKind() == ElementKind.CLASS) { + ClassName providerClassName = ClassName.get((TypeElement) element); + Provider provider = element.getAnnotation(Provider.class); + initBuilder.addStatement("$T $N = new $T()", providerClassName, providerClassName.simpleName().toLowerCase(), providerClassName); + initBuilder.addCode("if( providerMap.get($S) == null ){\n", provider.processName()); + initBuilder.addCode("providerMap.put($S, new $T());\n}\n", provider.processName(), arrayList); + initBuilder.addCode("(($T)providerMap.get($S)).add($N);\n", arrayList, provider.processName(), providerClassName.simpleName().toLowerCase()); + } + } + + for (Element element : actionList) { + if (element.getKind() == ElementKind.CLASS) { + Action action = element.getAnnotation(Action.class); + ClassName actionClassName = ClassName.get((TypeElement) element); + initBuilder.addStatement("$T $N = new $T()", actionClassName, actionClassName.simpleName().toLowerCase(), actionClassName); + String key = action.processName() + "_" + action.providerName(); + initBuilder.addCode("if(actionMap.get($S) == null ){\n", key); + initBuilder.addCode("actionMap.put($S, new $T());\n}\n", key, arrayList); + initBuilder.addCode("(($T)actionMap.get($S)).add($N);\n", arrayList, key, actionClassName.simpleName().toLowerCase()); + } + } + TypeSpec providerInit = TypeSpec.classBuilder(fileName) + .addModifiers(Modifier.PUBLIC) + .addMethod(initBuilder.build()) + .build(); + try { + JavaFile.builder("com.provider", providerInit) + .build() + .writeTo(filer); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + private void debug(String msg) { + messager.printMessage(Diagnostic.Kind.NOTE, msg); + } +} diff --git a/gradle.properties b/gradle.properties index aac7c9b..562a3e1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,3 +15,4 @@ org.gradle.jvmargs=-Xmx1536m # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true +Local = true \ No newline at end of file diff --git a/macore/bintray.gradle b/macore/bintray.gradle deleted file mode 100644 index 4088419..0000000 --- a/macore/bintray.gradle +++ /dev/null @@ -1,79 +0,0 @@ -apply plugin: 'com.github.dcendents.android-maven' -apply plugin: 'com.jfrog.bintray' -// This is the library version used when deploying the artifact -version = "0.1.2" - -def siteUrl = 'https://github.com/SpinyTech/ModularizationArchitecture' // 项目的主页 -def gitUrl = 'https://github.com/SpinyTech/ModularizationArchitecture.git' // Git仓库的url -group = "com.spinytech.ma" // Maven Group ID for the artifact,一般填你唯一的包名 -install { - repositories.mavenInstaller { - // This generates POM.xml with proper parameters - pom { - project { - packaging 'aar' - // Add your description here - name 'ModularizationArchitecture' - description 'A modularization architecture for Android program.' - url siteUrl - // Set your license - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } - developers { - developer { - id 'spiny' //填写的一些基本信息 - name 'spiny' - email 'spiny.tech@gmail.com' - } - } - scm { - connection gitUrl - developerConnection gitUrl - url siteUrl - } - } - } - } -} -task sourcesJar(type: Jar) { - from android.sourceSets.main.java.srcDirs - classifier = 'sources' -} -task javadoc(type: Javadoc) { - source = android.sourceSets.main.java.srcDirs - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) -} -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} -artifacts { - archives javadocJar - archives sourcesJar -} -Properties properties = new Properties() -properties.load(project.rootProject.file('local.properties').newDataInputStream()) -bintray { - user = properties.getProperty("bintray.user") - key = properties.getProperty("bintray.apikey") - configurations = ['archives'] - pkg { - repo = "ModularizationArchitecture" - name = "core" //发布到JCenter上的项目名字 -// userOrg = properties.getProperty("bintray.organizationId") - websiteUrl = siteUrl - vcsUrl = gitUrl - licenses = ["Apache-2.0"] - publish = true - } -} -javadoc { //jav doc采用utf-8编码否则会报“GBK的不可映射字符”错误 - options{ - encoding "UTF-8" - charSet 'UTF-8' - } -} \ No newline at end of file diff --git a/macore/build.gradle b/macore/build.gradle index eccc2c4..22a5d3d 100644 --- a/macore/build.gradle +++ b/macore/build.gradle @@ -22,12 +22,19 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) + compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:25.+' + provided project(':stub') + compile 'io.reactivex.rxjava2:rxandroid:2.0.1' + compile 'io.reactivex.rxjava2:rxjava:2.0.1' + if (Local.toBoolean()){ + compile project(':annotation') + }else{ + compile 'com.github.wutongke.modularization:annotation:1.0.0' + } } -apply from: "bintray.gradle" diff --git a/macore/src/main/aidl/com/spinytech/macore/ILocalRouterAIDL.aidl b/macore/src/main/aidl/com/spinytech/macore/ILocalRouterAIDL.aidl deleted file mode 100644 index 4d4c2c2..0000000 --- a/macore/src/main/aidl/com/spinytech/macore/ILocalRouterAIDL.aidl +++ /dev/null @@ -1,9 +0,0 @@ -package com.spinytech.macore; - - -interface ILocalRouterAIDL { - boolean checkResponseAsync(String routerRequset); - String route(String routerRequest); - boolean stopWideRouter(); - void connectWideRouter(); -} diff --git a/macore/src/main/aidl/com/spinytech/macore/IWideRouterAIDL.aidl b/macore/src/main/aidl/com/spinytech/macore/IWideRouterAIDL.aidl deleted file mode 100644 index 84245bc..0000000 --- a/macore/src/main/aidl/com/spinytech/macore/IWideRouterAIDL.aidl +++ /dev/null @@ -1,10 +0,0 @@ -// IRouterAIDL.aidl -package com.spinytech.macore; - -// Declare any non-default types here with import statements - -interface IWideRouterAIDL { - boolean checkResponseAsync(String domain,String routerRequset); - String route(String domain,String routerRequest); - boolean stopRouter(String domain); -} diff --git a/macore/src/main/aidl/com/spinytech/macore/router/ILocalRouterAIDL.aidl b/macore/src/main/aidl/com/spinytech/macore/router/ILocalRouterAIDL.aidl new file mode 100644 index 0000000..565d119 --- /dev/null +++ b/macore/src/main/aidl/com/spinytech/macore/router/ILocalRouterAIDL.aidl @@ -0,0 +1,10 @@ +package com.spinytech.macore.router; +import com.spinytech.macore.router.MaActionResult; +import com.spinytech.macore.router.RouterRequest; + +interface ILocalRouterAIDL { + boolean checkResponseAsync(in RouterRequest routerRequset); + MaActionResult route(in RouterRequest routerRequest); + boolean stopWideRouter(); + void connectWideRouter(); +} diff --git a/macore/src/main/aidl/com/spinytech/macore/router/IWideRouterAIDL.aidl b/macore/src/main/aidl/com/spinytech/macore/router/IWideRouterAIDL.aidl new file mode 100644 index 0000000..6a8cead --- /dev/null +++ b/macore/src/main/aidl/com/spinytech/macore/router/IWideRouterAIDL.aidl @@ -0,0 +1,11 @@ +// IRouterAIDL.aidl +package com.spinytech.macore.router; +import com.spinytech.macore.router.MaActionResult; +import com.spinytech.macore.router.RouterRequest; +// Declare any non-default types here with import statements + +interface IWideRouterAIDL { + boolean checkResponseAsync(String domain,in RouterRequest routerRequset); + MaActionResult route(String domain,in RouterRequest routerRequest); + boolean stopRouter(String domain); +} diff --git a/macore/src/main/aidl/com/spinytech/macore/router/MaActionResult.aidl b/macore/src/main/aidl/com/spinytech/macore/router/MaActionResult.aidl new file mode 100644 index 0000000..fc1f76c --- /dev/null +++ b/macore/src/main/aidl/com/spinytech/macore/router/MaActionResult.aidl @@ -0,0 +1,3 @@ +package com.spinytech.macore.router; +// Declare any non-default types here with import statements +parcelable MaActionResult; diff --git a/macore/src/main/aidl/com/spinytech/macore/router/RouterRequest.aidl b/macore/src/main/aidl/com/spinytech/macore/router/RouterRequest.aidl new file mode 100644 index 0000000..2d63854 --- /dev/null +++ b/macore/src/main/aidl/com/spinytech/macore/router/RouterRequest.aidl @@ -0,0 +1,3 @@ +package com.spinytech.macore.router; +// Declare any non-default types here with import statements +parcelable RouterRequest; diff --git a/macore/src/main/java/com/spinytech/macore/ErrorAction.java b/macore/src/main/java/com/spinytech/macore/ErrorAction.java index 9a1416e..8cb26f4 100644 --- a/macore/src/main/java/com/spinytech/macore/ErrorAction.java +++ b/macore/src/main/java/com/spinytech/macore/ErrorAction.java @@ -2,13 +2,14 @@ import android.content.Context; -import java.util.HashMap; +import com.spinytech.macore.router.MaActionResult; +import com.spinytech.macore.router.RouterRequest; /** * Created by wanglei on 2016/12/28. */ -public class ErrorAction extends MaAction { +public class ErrorAction implements MaAction { private static final String DEFAULT_MESSAGE = "Something was really wrong. Ha ha!"; private int mCode; @@ -27,19 +28,24 @@ public ErrorAction(boolean isAsync,int code, String message) { } @Override - public boolean isAsync(Context context, HashMap requestData) { + public boolean isAsync(Context context, RouterRequest requestData) { return mAsync; } @Override - public MaActionResult invoke(Context context, HashMap requestData) { + public MaActionResult invoke(Context context, RouterRequest requestData) { MaActionResult result = new MaActionResult.Builder() .code(mCode) .msg(mMessage) .data(null) - .object(null) + .result(null) .build(); return result; } + @Override + public String getName() { + return "error"; + } + } diff --git a/macore/src/main/java/com/spinytech/macore/MaAction.java b/macore/src/main/java/com/spinytech/macore/MaAction.java index c8621a0..e7a4393 100644 --- a/macore/src/main/java/com/spinytech/macore/MaAction.java +++ b/macore/src/main/java/com/spinytech/macore/MaAction.java @@ -2,13 +2,17 @@ import android.content.Context; -import java.util.HashMap; +import com.spinytech.macore.router.MaActionResult; +import com.spinytech.macore.router.RouterRequest; /** * Created by wanglei on 2016/11/29. */ -public abstract class MaAction { - public abstract boolean isAsync(Context context, HashMap requestData); - public abstract MaActionResult invoke(Context context, HashMap requestData); +public interface MaAction { + boolean isAsync(Context context, RouterRequest routerRequest); + + MaActionResult invoke(Context context, RouterRequest routerRequest); + + String getName(); } diff --git a/macore/src/main/java/com/spinytech/macore/MaActionResult.java b/macore/src/main/java/com/spinytech/macore/MaActionResult.java deleted file mode 100644 index 8a65768..0000000 --- a/macore/src/main/java/com/spinytech/macore/MaActionResult.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.spinytech.macore; - - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Created by wanglei on 16/6/14. - */ -public class MaActionResult { - public static final int CODE_SUCCESS = 0x0000; - public static final int CODE_ERROR = 0x0001; - public static final int CODE_NOT_FOUND = 0X0002; - public static final int CODE_INVALID = 0X0003; - public static final int CODE_ROUTER_NOT_REGISTER = 0X0004; - public static final int CODE_CANNOT_BIND_LOCAL = 0X0005; - public static final int CODE_REMOTE_EXCEPTION = 0X0006; - public static final int CODE_CANNOT_BIND_WIDE = 0X0007; - public static final int CODE_TARGET_IS_WIDE = 0X0008; - public static final int CODE_WIDE_STOPPING = 0X0009; - - private int code; - private String msg; - private String data; - private Object object; - - private MaActionResult(Builder builder) { - this.code = builder.mCode; - this.msg = builder.mMsg; - this.data = builder.mData; - this.object = builder.mObject; - } - - public Object getObject() { - return object; - } - - public String getData() { - return data; - } - - public int getCode() { - return code; - } - - public String getMsg() { - return msg; - } - - @Override - public String toString() { - JSONObject jsonObject = new JSONObject(); - try { - jsonObject.put("code", code); - jsonObject.put("msg", msg); - jsonObject.put("data", data); - } catch (JSONException e) { - e.printStackTrace(); - } - return jsonObject.toString(); - } - - public static class Builder { - private int mCode; - private String mMsg; - private Object mObject; - private String mData; - - public Builder() { - mCode = CODE_ERROR; - mMsg = ""; - mObject = null; - mData = null; - } - - public Builder resultString(String resultString) { - try { - JSONObject jsonObject = new JSONObject(resultString); - this.mCode = jsonObject.getInt("code"); - this.mMsg = jsonObject.getString("msg"); - this.mData = jsonObject.getString("data"); - } catch (JSONException e) { - e.printStackTrace(); - } - return this; - } - - public Builder code(int code) { - this.mCode = code; - return this; - } - - public Builder msg(String msg) { - this.mMsg = msg; - return this; - } - - public Builder data(String data) { - this.mData = data; - return this; - } - - public Builder object(Object object) { - this.mObject = object; - return this; - } - - public MaActionResult build() { - return new MaActionResult(this); - } - } - - -} diff --git a/macore/src/main/java/com/spinytech/macore/MaApplication.java b/macore/src/main/java/com/spinytech/macore/MaApplication.java index c6beb90..7407a50 100644 --- a/macore/src/main/java/com/spinytech/macore/MaApplication.java +++ b/macore/src/main/java/com/spinytech/macore/MaApplication.java @@ -5,7 +5,9 @@ import android.content.res.Configuration; import android.support.annotation.CallSuper; import android.support.annotation.NonNull; +import android.util.Log; +import com.provider.ProviderInit; import com.spinytech.macore.multiprocess.BaseApplicationLogic; import com.spinytech.macore.multiprocess.PriorityLogicWrapper; import com.spinytech.macore.router.LocalRouter; @@ -28,13 +30,15 @@ public abstract class MaApplication extends Application { private static MaApplication sInstance; private ArrayList mLogicList; private HashMap> mLogicClassMap; + private HashMap> mProviderMap; + private HashMap> mActionMap; @CallSuper @Override public void onCreate() { super.onCreate(); sInstance = this; - Logger.d(TAG,"Application onCreate start: "+System.currentTimeMillis()); + Logger.d(TAG, "Application onCreate start: " + System.currentTimeMillis()); init(); startWideRouter(); initializeLogic(); @@ -46,15 +50,28 @@ public void onCreate() { for (PriorityLogicWrapper priorityLogicWrapper : mLogicList) { if (null != priorityLogicWrapper && null != priorityLogicWrapper.instance) { priorityLogicWrapper.instance.onCreate(); + String precessName = ProcessUtil.getProcessName(this, ProcessUtil.getMyProcessId()); + Logger.d(TAG, precessName); + if(mProviderMap.get(precessName)!= null){ + for (MaProvider maProvider : mProviderMap.get(precessName)) { + LocalRouter.getInstance(this).registerProvider(maProvider.getName(), maProvider); + for (MaAction maAction : mActionMap.get(precessName + "_" + maProvider.getName())) { + maProvider.registerAction(maAction.getName(), maAction); + } + } + } } } } - Logger.d(TAG,"Application onCreate end: "+System.currentTimeMillis()); + Logger.d(TAG, "Application onCreate end: " + System.currentTimeMillis()); } private void init() { LocalRouter.getInstance(this); mLogicClassMap = new HashMap<>(); + mProviderMap = new HashMap<>(); + mActionMap = new HashMap<>(); + ProviderInit.init(mProviderMap, mActionMap); } protected void startWideRouter() { @@ -168,7 +185,7 @@ public void onConfigurationChanged(Configuration newConfig) { } } - public static MaApplication getMaApplication(){ + public static MaApplication getMaApplication() { return sInstance; } } diff --git a/macore/src/main/java/com/spinytech/macore/MaProvider.java b/macore/src/main/java/com/spinytech/macore/MaProvider.java index 3822826..92e3a22 100644 --- a/macore/src/main/java/com/spinytech/macore/MaProvider.java +++ b/macore/src/main/java/com/spinytech/macore/MaProvider.java @@ -12,7 +12,6 @@ public abstract class MaProvider{ private HashMap mActions; public MaProvider(){ mActions = new HashMap<>(); - registerActions(); } protected void registerAction(String actionName,MaAction action){ mActions.put(actionName,action); @@ -26,5 +25,5 @@ public boolean isValid(){ return mValid; } - protected abstract void registerActions(); + protected abstract String getName(); } diff --git a/macore/src/main/java/com/spinytech/macore/Song.java b/macore/src/main/java/com/spinytech/macore/Song.java new file mode 100644 index 0000000..21475b0 --- /dev/null +++ b/macore/src/main/java/com/spinytech/macore/Song.java @@ -0,0 +1,42 @@ +package com.spinytech.macore; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Created by erfli on 2/14/17. + */ + +public class Song implements Parcelable { + public String name; + + public Song(String name) { + this.name = name; + } + + protected Song(Parcel in) { + name = in.readString(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(name); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public Song createFromParcel(Parcel in) { + return new Song(in); + } + + @Override + public Song[] newArray(int size) { + return new Song[size]; + } + }; +} diff --git a/macore/src/main/java/com/spinytech/macore/router/LocalRouter.java b/macore/src/main/java/com/spinytech/macore/router/LocalRouter.java index fb03b15..eeb3bc8 100644 --- a/macore/src/main/java/com/spinytech/macore/router/LocalRouter.java +++ b/macore/src/main/java/com/spinytech/macore/router/LocalRouter.java @@ -9,9 +9,7 @@ import android.support.annotation.NonNull; import com.spinytech.macore.ErrorAction; -import com.spinytech.macore.IWideRouterAIDL; import com.spinytech.macore.MaAction; -import com.spinytech.macore.MaActionResult; import com.spinytech.macore.MaApplication; import com.spinytech.macore.MaProvider; import com.spinytech.macore.tools.Logger; @@ -22,6 +20,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import io.reactivex.Observable; + import static android.content.Context.BIND_AUTO_CREATE; /** @@ -64,9 +64,11 @@ public static synchronized LocalRouter getInstance(@NonNull MaApplication contex return sInstance; } - private static synchronized ExecutorService getThreadPool() { + private static ExecutorService getThreadPool() { if (null == threadPool) { - threadPool = Executors.newCachedThreadPool(); + synchronized (LocalRouter.class) { + threadPool = Executors.newCachedThreadPool(); + } } return threadPool; } @@ -100,68 +102,103 @@ public boolean checkWideRouterConnection() { boolean answerWiderAsync(@NonNull RouterRequest routerRequest) { if (mProcessName.equals(routerRequest.getDomain()) && checkWideRouterConnection()) { - return findRequestAction(routerRequest).isAsync(mApplication, routerRequest.getData()); + return findRequestAction(routerRequest).isAsync(mApplication, routerRequest); } else { return true; } } - public RouterResponse route(Context context, @NonNull RouterRequest routerRequest) throws Exception { - Logger.d(TAG, "Process:" + mProcessName + "\nLocal route start: " + System.currentTimeMillis()); - RouterResponse routerResponse = new RouterResponse(); + private static class RouteResultWrap{ + MaActionResult maActionResult; + Observable maActionResultObservable; + } + + + public MaActionResult route(Context context, @NonNull RouterRequest routerRequest) throws Exception { + RouteResultWrap routeResultWrap = new RouteResultWrap(); + rxRoute(context, routerRequest, routeResultWrap, RouteResultType.MA_ACTION_RESULT); + return routeResultWrap.maActionResult; + } + + public Observable rxRoute(Context context, @NonNull RouterRequest routerRequest) throws Exception { + RouteResultWrap routeResultWrap= new RouteResultWrap(); + rxRoute(context, routerRequest, routeResultWrap, RouteResultType.OBSERVABLE); + return routeResultWrap.maActionResultObservable; + } + + private void rxRoute(Context context, @NonNull RouterRequest routerRequest, RouteResultWrap routeResultWrap, RouteResultType type) throws Exception { + Logger.d(TAG, "Process:" + mProcessName + "\nLocal rxRoute start: " + System.currentTimeMillis()); // Local request if (mProcessName.equals(routerRequest.getDomain())) { - HashMap params = new HashMap<>(); - params.putAll(routerRequest.getData()); Logger.d(TAG, "Process:" + mProcessName + "\nLocal find action start: " + System.currentTimeMillis()); MaAction targetAction = findRequestAction(routerRequest); routerRequest.isIdle.set(true); Logger.d(TAG, "Process:" + mProcessName + "\nLocal find action end: " + System.currentTimeMillis()); - routerResponse.mIsAsync = targetAction.isAsync(context, params); // Sync result, return the result immediately. - if (!routerResponse.mIsAsync) { - MaActionResult result = targetAction.invoke(context, params); - routerResponse.mResultString = result.toString(); - routerResponse.mObject = result.getObject(); + if (!targetAction.isAsync(context, routerRequest)) { + routeResultWrap.maActionResult = targetAction.invoke(context, routerRequest); Logger.d(TAG, "Process:" + mProcessName + "\nLocal sync end: " + System.currentTimeMillis()); + if (type == RouteResultType.OBSERVABLE) { + routeResultWrap.maActionResultObservable = Observable.just(routeResultWrap.maActionResult); + return; + } else { + return; + } } // Async result, use the thread pool to execute the task. else { - LocalTask task = new LocalTask(routerResponse, params, context, targetAction); - routerResponse.mAsyncResponse = getThreadPool().submit(task); + LocalTask task = new LocalTask(routerRequest, context, targetAction); + if (type == RouteResultType.OBSERVABLE) { + routeResultWrap.maActionResultObservable = Observable.fromFuture(getThreadPool().submit(task)); + } else { + routeResultWrap.maActionResult = getThreadPool().submit(task).get(); + } + return; } } else if (!mApplication.needMultipleProcess()) { - throw new Exception("Please make sure the returned value of needMultipleProcess in MaApplication is true, so that you can invoke other process action."); + throw new RuntimeException("Please make sure the returned value of needMultipleProcess in MaApplication is true, so that you can invoke other process action."); } // IPC request else { String domain = routerRequest.getDomain(); - String routerRequestString = routerRequest.toString(); routerRequest.isIdle.set(true); + boolean mIsAsync = false; if (checkWideRouterConnection()) { Logger.d(TAG, "Process:" + mProcessName + "\nWide async check start: " + System.currentTimeMillis()); - //If you don't need wide async check, use "routerResponse.mIsAsync = false;" replace the next line to improve performance. - routerResponse.mIsAsync = mWideRouterAIDL.checkResponseAsync(domain, routerRequestString); + //If you don'requestObject need wide async check, use "maActionResult.mIsAsync = false;" replace the next line to improve performance. + mIsAsync = mWideRouterAIDL.checkResponseAsync(domain, routerRequest); Logger.d(TAG, "Process:" + mProcessName + "\nWide async check end: " + System.currentTimeMillis()); + if (!mIsAsync) { + Logger.d(TAG, "Process:" + mProcessName + "\nWide sync end: " + System.currentTimeMillis()); + if (type == RouteResultType.OBSERVABLE) { + routeResultWrap.maActionResultObservable = Observable.just(mWideRouterAIDL.route(domain, routerRequest)); + } else { + routeResultWrap.maActionResult = mWideRouterAIDL.route(domain, routerRequest); + } + return; + } + // Async result, use the thread pool to execute the task. + else { + WideTask task = new WideTask(domain, routerRequest); + if (type == RouteResultType.OBSERVABLE) { + routeResultWrap.maActionResultObservable = Observable.fromFuture(getThreadPool().submit(task)); + } else { + routeResultWrap.maActionResult = getThreadPool().submit(task).get(); + } + return; + } } // Has not connected with the wide router. else { - routerResponse.mIsAsync = true; - ConnectWideTask task = new ConnectWideTask(routerResponse, domain, routerRequestString); - routerResponse.mAsyncResponse = getThreadPool().submit(task); - return routerResponse; - } - if (!routerResponse.mIsAsync) { - routerResponse.mResultString = mWideRouterAIDL.route(domain, routerRequestString); - Logger.d(TAG, "Process:" + mProcessName + "\nWide sync end: " + System.currentTimeMillis()); - } - // Async result, use the thread pool to execute the task. - else { - WideTask task = new WideTask(domain, routerRequestString); - routerResponse.mAsyncResponse = getThreadPool().submit(task); + ConnectWideTask task = new ConnectWideTask(domain, routerRequest); + if (type == RouteResultType.OBSERVABLE) { + routeResultWrap.maActionResultObservable = Observable.fromFuture(getThreadPool().submit(task)); + } else { + routeResultWrap.maActionResult = getThreadPool().submit(task).get(); + } + return; } } - return routerResponse; } public boolean stopSelf(Class clazz) { @@ -186,7 +223,7 @@ public void stopWideRouter() { e.printStackTrace(); } } else { - Logger.e(TAG, "This local router hasn't connected the wide router."); + Logger.e(TAG, "This local router hasn'requestObject connected the wide router."); } } @@ -205,60 +242,55 @@ private MaAction findRequestAction(RouterRequest routerRequest) { } } - private class LocalTask implements Callable { - private RouterResponse mResponse; - private HashMap mRequestData; + private class LocalTask implements Callable { + private RouterRequest mRequestData; private Context mContext; private MaAction mAction; - public LocalTask(RouterResponse routerResponse, HashMap requestData, Context context, MaAction maAction) { + public LocalTask(RouterRequest requestData, Context context, MaAction maAction) { this.mContext = context; - this.mResponse = routerResponse; this.mRequestData = requestData; this.mAction = maAction; } @Override - public String call() throws Exception { + public MaActionResult call() throws Exception { MaActionResult result = mAction.invoke(mContext, mRequestData); - mResponse.mObject = result.getObject(); Logger.d(TAG, "Process:" + mProcessName + "\nLocal async end: " + System.currentTimeMillis()); - return result.toString(); + return result; } } - private class WideTask implements Callable { + private class WideTask implements Callable { private String mDomain; - private String mRequestString; + private RouterRequest routerRequest; - public WideTask(String domain, String requestString) { + public WideTask(String domain, RouterRequest routerRequest) { this.mDomain = domain; - this.mRequestString = requestString; + this.routerRequest = routerRequest; } @Override - public String call() throws Exception { + public MaActionResult call() throws Exception { Logger.d(TAG, "Process:" + mProcessName + "\nWide async start: " + System.currentTimeMillis()); - String result = mWideRouterAIDL.route(mDomain, mRequestString); + MaActionResult result = mWideRouterAIDL.route(mDomain, routerRequest); Logger.d(TAG, "Process:" + mProcessName + "\nWide async end: " + System.currentTimeMillis()); return result; } } - private class ConnectWideTask implements Callable { - private RouterResponse mResponse; + private class ConnectWideTask implements Callable { private String mDomain; - private String mRequestString; + private RouterRequest routerRequest; - public ConnectWideTask(RouterResponse routerResponse, String domain, String requestString) { - this.mResponse = routerResponse; + public ConnectWideTask(String domain, RouterRequest routerRequest) { this.mDomain = domain; - this.mRequestString = requestString; + this.routerRequest = routerRequest; } @Override - public String call() throws Exception { + public MaActionResult call() throws Exception { Logger.d(TAG, "Process:" + mProcessName + "\nBind wide router start: " + System.currentTimeMillis()); connectWideRouter(); int time = 0; @@ -275,15 +307,18 @@ public String call() throws Exception { } if (time >= 600) { ErrorAction defaultNotFoundAction = new ErrorAction(true, MaActionResult.CODE_CANNOT_BIND_WIDE, "Bind wide router time out. Can not bind wide router."); - MaActionResult result = defaultNotFoundAction.invoke(mApplication, new HashMap()); - mResponse.mResultString = result.toString(); - return result.toString(); + return defaultNotFoundAction.invoke(mApplication, new RouterRequest()); } } Logger.d(TAG, "Process:" + mProcessName + "\nBind wide router end: " + System.currentTimeMillis()); - String result = mWideRouterAIDL.route(mDomain, mRequestString); + MaActionResult result = mWideRouterAIDL.route(mDomain, routerRequest); Logger.d(TAG, "Process:" + mProcessName + "\nWide async end: " + System.currentTimeMillis()); return result; } } + + private enum RouteResultType { + OBSERVABLE, + MA_ACTION_RESULT + } } diff --git a/macore/src/main/java/com/spinytech/macore/router/LocalRouterConnectService.java b/macore/src/main/java/com/spinytech/macore/router/LocalRouterConnectService.java index 87e5d56..a016ec1 100644 --- a/macore/src/main/java/com/spinytech/macore/router/LocalRouterConnectService.java +++ b/macore/src/main/java/com/spinytech/macore/router/LocalRouterConnectService.java @@ -7,8 +7,6 @@ import android.support.annotation.Nullable; import android.util.Log; -import com.spinytech.macore.ILocalRouterAIDL; -import com.spinytech.macore.MaActionResult; import com.spinytech.macore.MaApplication; /** @@ -32,27 +30,20 @@ public IBinder onBind(Intent intent) { ILocalRouterAIDL.Stub stub = new ILocalRouterAIDL.Stub() { @Override - public boolean checkResponseAsync(String routerRequest) throws RemoteException { + public boolean checkResponseAsync(RouterRequest routerRequest) throws RemoteException { return LocalRouter.getInstance(MaApplication.getMaApplication()). - answerWiderAsync(new RouterRequest - .Builder(getApplicationContext()) - .json(routerRequest) - .build()); + answerWiderAsync(routerRequest); } @Override - public String route(String routerRequest) { + public MaActionResult route(RouterRequest routerRequest) { try { LocalRouter localRouter = LocalRouter.getInstance(MaApplication.getMaApplication()); - RouterRequest routerRequest1 = new RouterRequest - .Builder(getApplicationContext()) - .json(routerRequest) - .build(); - RouterResponse routerResponse = localRouter.route(LocalRouterConnectService.this,routerRequest1); - return routerResponse.get(); + RouterRequest routerRequest1 = routerRequest; + return localRouter.route(LocalRouterConnectService.this,routerRequest1); } catch (Exception e) { e.printStackTrace(); - return new MaActionResult.Builder().msg(e.getMessage()).build().toString(); + return new MaActionResult.Builder().msg(e.getMessage()).build(); } } diff --git a/macore/src/main/java/com/spinytech/macore/router/MaActionResult.java b/macore/src/main/java/com/spinytech/macore/router/MaActionResult.java new file mode 100644 index 0000000..2fdd1b4 --- /dev/null +++ b/macore/src/main/java/com/spinytech/macore/router/MaActionResult.java @@ -0,0 +1,130 @@ +package com.spinytech.macore.router; + + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Created by wanglei on 16/6/14. + */ +public class MaActionResult implements Parcelable { + public static final int CODE_SUCCESS = 0x0000; + public static final int CODE_ERROR = 0x0001; + public static final int CODE_NOT_FOUND = 0X0002; + public static final int CODE_INVALID = 0X0003; + public static final int CODE_ROUTER_NOT_REGISTER = 0X0004; + public static final int CODE_CANNOT_BIND_LOCAL = 0X0005; + public static final int CODE_REMOTE_EXCEPTION = 0X0006; + public static final int CODE_CANNOT_BIND_WIDE = 0X0007; + public static final int CODE_TARGET_IS_WIDE = 0X0008; + public static final int CODE_WIDE_STOPPING = 0X0009; + + private int code; + private String msg; + private String data; + private T result; + + MaActionResult(){ + + } + + private MaActionResult(Builder builder) { + code = builder.code; + msg = builder.msg; + data = builder.data; + result = (T) builder.result; + } + + protected MaActionResult(Parcel in) { + code = in.readInt(); + msg = in.readString(); + data = in.readString(); + result = (T) in.readParcelable(this.getClass().getClassLoader()); + } + + public static final Creator CREATOR = new Creator() { + @Override + public MaActionResult createFromParcel(Parcel in) { + return new MaActionResult(in); + } + + @Override + public MaActionResult[] newArray(int size) { + return new MaActionResult[size]; + } + }; + + public Object getResult() { + return result; + } + + public String getData() { + return data; + } + + public int getCode() { + return code; + } + + public String getMsg() { + return msg; + } + + @Override + public String toString() { + return "MaActionResult{" + + "code=" + code + + ", msg='" + msg + '\'' + + ", data='" + data + '\'' + + ", object=" + result + + '}'; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(code); + dest.writeString(msg); + dest.writeString(data); + dest.writeParcelable((Parcelable) result, flags); + } + + + public static final class Builder { + private int code; + private String msg; + private String data; + private T result; + + public Builder() { + } + + public Builder code(int val) { + code = val; + return this; + } + + public Builder msg(String val) { + msg = val; + return this; + } + + public Builder data(String val) { + data = val; + return this; + } + + public Builder result(T val) { + result = val; + return this; + } + + public MaActionResult build() { + return new MaActionResult(this); + } + } +} diff --git a/macore/src/main/java/com/spinytech/macore/router/RouterRequest.java b/macore/src/main/java/com/spinytech/macore/router/RouterRequest.java index f85c520..6474091 100644 --- a/macore/src/main/java/com/spinytech/macore/router/RouterRequest.java +++ b/macore/src/main/java/com/spinytech/macore/router/RouterRequest.java @@ -1,18 +1,13 @@ package com.spinytech.macore.router; import android.content.Context; -import android.text.TextUtils; - -import com.spinytech.macore.tools.Logger; -import com.spinytech.macore.tools.ProcessUtil; +import android.os.Parcel; +import android.os.Parcelable; import org.json.JSONException; import org.json.JSONObject; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -21,52 +16,68 @@ * Created by wanglei on 2016/12/27. */ -public class RouterRequest { - private static final String TAG = "RouterRequest"; - private static volatile String DEFAULT_PROCESS=""; - private String from; - private String domain; - private String provider; - private String action; - private HashMap data; - AtomicBoolean isIdle = new AtomicBoolean(true); +public class RouterRequest implements Parcelable { + static AtomicInteger sIndex = new AtomicInteger(0); - private static final int length = 64; - private static AtomicInteger sIndex = new AtomicInteger(0); - private static final int RESET_NUM = 1000; - private static volatile RouterRequest[] table = new RouterRequest[length]; + String from; + String domain; + String provider; + String action; + HashMap data; + T requestObject; - static { - for (int i = 0; i < length; i++) { - table[i] = new RouterRequest(); - } - } + public AtomicBoolean isIdle = new AtomicBoolean(true); - private RouterRequest() { - this.from = DEFAULT_PROCESS; - this.domain = DEFAULT_PROCESS; + public RouterRequest() { + this.from = RouterRequestUtil.DEFAULT_PROCESS; + this.domain = RouterRequestUtil.DEFAULT_PROCESS; this.provider = ""; this.action = ""; this.data = new HashMap<>(); } - private RouterRequest(Context context) { - this.from = getProcess(context); - this.domain = getProcess(context); + RouterRequest(Context context) { + this.from = RouterRequestUtil.getProcess(context); + this.domain = RouterRequestUtil.getProcess(context); this.provider = ""; this.action = ""; this.data = new HashMap<>(); } - private RouterRequest(Builder builder) { - this.from = builder.mFrom; - this.domain = builder.mDomain; - this.provider = builder.mProvider; - this.action = builder.mAction; - this.data = builder.mData; + protected RouterRequest(Parcel in) { + from = in.readString(); + domain = in.readString(); + provider = in.readString(); + action = in.readString(); + requestObject = (T) in.readParcelable(this.getClass().getClassLoader()); + int mapSize = in.readInt(); + if (mapSize > 0) { + data = new HashMap<>(); + } + for (int i = 0; i < mapSize; i++) { + String key = in.readString(); + String value = in.readString(); + data.put(key, value); + } + } + + public T getRequestObject() { + return requestObject; } + public static final Creator CREATOR = new Creator() { + @Override + public RouterRequest createFromParcel(Parcel in) { + return new RouterRequest(in); + } + + @Override + public RouterRequest[] newArray(int size) { + return new RouterRequest[size]; + } + }; + public String getFrom() { return from; } @@ -87,15 +98,7 @@ public HashMap getData() { return data; } - private static String getProcess(Context context) { - if (TextUtils.isEmpty(DEFAULT_PROCESS) || ProcessUtil.UNKNOWN_PROCESS_NAME.equals(DEFAULT_PROCESS)) { - DEFAULT_PROCESS = ProcessUtil.getProcessName(context, ProcessUtil.getMyProcessId()); - } - return DEFAULT_PROCESS; - } - - @Override - public String toString() { + public String toJsonString() { //Here remove Gson to save about 10ms. //String result = new Gson().toJson(this); JSONObject jsonObject = new JSONObject(); @@ -122,79 +125,6 @@ public String toString() { return jsonObject.toString(); } - public RouterRequest json(String requestJsonString) { - //Here remove Gson to save about 10ms. - //RouterRequest routerRequest = new Gson().fromJson(requestJsonString, RouterRequest.class); - try { - JSONObject jsonObject = new JSONObject(requestJsonString); - this.from = jsonObject.getString("from"); - this.domain = jsonObject.getString("domain"); - this.provider = jsonObject.getString("provider"); - this.action = jsonObject.getString("action"); - try { - JSONObject jsonData = new JSONObject(jsonObject.getString("data")); - Iterator it = jsonData.keys(); - while (it.hasNext()) { - String key = String.valueOf(it.next()); - String value = (String) jsonData.get(key); - this.data.put(key, value); - } - } catch (Exception e) { - e.printStackTrace(); - this.data = new HashMap<>(); - } - } catch (JSONException e) { - e.printStackTrace(); - } - return this; - } - - public RouterRequest url(String url) { - int questIndex = url.indexOf('?'); - String[] urls = url.split("\\?"); - if (urls.length != 1 && urls.length != 2) { - Logger.e(TAG, "The url is illegal."); - return this; - } - String[] targets = urls[0].split("/"); - if (targets.length == 3) { - this.domain = targets[0]; - this.provider = targets[1]; - this.action = targets[2]; - } else { - Logger.e(TAG, "The url is illegal."); - return this; - } - //Add params - if (questIndex != -1) { - String queryString = urls[1]; - if (queryString != null && queryString.length() > 0) { - int ampersandIndex, lastAmpersandIndex = 0; - String subStr, key, value; - String[] paramPair, values, newValues; - do { - ampersandIndex = queryString.indexOf('&', lastAmpersandIndex) + 1; - if (ampersandIndex > 0) { - subStr = queryString.substring(lastAmpersandIndex, ampersandIndex - 1); - lastAmpersandIndex = ampersandIndex; - } else { - subStr = queryString.substring(lastAmpersandIndex); - } - paramPair = subStr.split("="); - key = paramPair[0]; - value = paramPair.length == 1 ? "" : paramPair[1]; - try { - value = URLDecoder.decode(value, "UTF-8"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - data.put(key, value); - } while (ampersandIndex > 0); - } - } - return this; - } - public RouterRequest domain(String domain) { this.domain = domain; return this; @@ -212,161 +142,36 @@ public RouterRequest action(String action) { return this; } + public RouterRequest reqeustObject(T t) { + this.requestObject = t; + return this; + } public RouterRequest data(String key, String data) { this.data.put(key, data); return this; } - public static RouterRequest obtain(Context context) { - return obtain(context,0); - } - - private static RouterRequest obtain(Context context,int retryTime) { - int index = sIndex.getAndIncrement(); - if (index > RESET_NUM) { - sIndex.compareAndSet(index, 0); - if (index > RESET_NUM * 2) { - sIndex.set(0); - } - } - - int num = index & (length - 1); - - RouterRequest target = table[num]; - - if (target.isIdle.compareAndSet(true, false)) { - target.from = getProcess(context); - target.domain = getProcess(context); - target.provider = ""; - target.action = ""; - target.data.clear(); - return target; - } else { - if (retryTime < 5) { - return obtain(context,retryTime++); - } else { - return new RouterRequest(context); - } - - } + @Override + public int describeContents() { + return 0; } - @Deprecated - public static class Builder { - private String mFrom; - private String mDomain; - private String mProvider; - private String mAction; - private HashMap mData; - - public Builder(Context context) { - mFrom = getProcess(context); - mDomain = getProcess(context); - mProvider = ""; - mAction = ""; - mData = new HashMap<>(); - } - - public Builder json(String requestJsonString) { - //Here remove Gson to save about 10ms. - //RouterRequest routerRequest = new Gson().fromJson(requestJsonString, RouterRequest.class); - try { - JSONObject jsonObject = new JSONObject(requestJsonString); - this.mFrom = jsonObject.getString("from"); - this.mDomain = jsonObject.getString("domain"); - this.mProvider = jsonObject.getString("provider"); - this.mAction = jsonObject.getString("action"); - try { - JSONObject jsonData = new JSONObject(jsonObject.getString("data")); - Iterator it = jsonData.keys(); - while (it.hasNext()) { - String key = String.valueOf(it.next()); - String value = (String) jsonData.get(key); - this.mData.put(key, value); - } - } catch (Exception e) { - e.printStackTrace(); - this.mData = new HashMap<>(); - } - } catch (JSONException e) { - e.printStackTrace(); - } - return this; - } - - public Builder url(String url) { - int questIndex = url.indexOf('?'); - String[] urls = url.split("\\?"); - if (urls.length != 1 && urls.length != 2) { - Logger.e(TAG, "The url is illegal."); - return this; - } - String[] targets = urls[0].split("/"); - if (targets.length == 3) { - this.mDomain = targets[0]; - this.mProvider = targets[1]; - this.mAction = targets[2]; - } else { - Logger.e(TAG, "The url is illegal."); - return this; - } - //Add params - if (questIndex != -1) { - String queryString = urls[1]; - if (queryString != null && queryString.length() > 0) { - int ampersandIndex, lastAmpersandIndex = 0; - String subStr, key, value; - String[] paramPair, values, newValues; - do { - ampersandIndex = queryString.indexOf('&', lastAmpersandIndex) + 1; - if (ampersandIndex > 0) { - subStr = queryString.substring(lastAmpersandIndex, ampersandIndex - 1); - lastAmpersandIndex = ampersandIndex; - } else { - subStr = queryString.substring(lastAmpersandIndex); - } - paramPair = subStr.split("="); - key = paramPair[0]; - value = paramPair.length == 1 ? "" : paramPair[1]; - try { - value = URLDecoder.decode(value, "UTF-8"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - mData.put(key, value); - } while (ampersandIndex > 0); - } + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(from); + dest.writeString(domain); + dest.writeString(provider); + dest.writeString(action); + dest.writeParcelable((Parcelable) requestObject, flags); + if(data !=null){ + dest.writeInt(data.size()); + for (Map.Entry entry : data.entrySet()) { + dest.writeString(entry.getKey()); + dest.writeString(entry.getValue()); } - return this; - } - - public Builder domain(String domain) { - this.mDomain = domain; - return this; - } - - - public Builder provider(String provider) { - this.mProvider = provider; - return this; - } - - - public Builder action(String action) { - this.mAction = action; - return this; - } - - - public Builder data(String key, String data) { - this.mData.put(key, data); - return this; - } - - public RouterRequest build() { - return new RouterRequest(this); + }else{ + dest.writeInt(0); } } - } diff --git a/macore/src/main/java/com/spinytech/macore/router/RouterRequestUtil.java b/macore/src/main/java/com/spinytech/macore/router/RouterRequestUtil.java new file mode 100644 index 0000000..806cfd0 --- /dev/null +++ b/macore/src/main/java/com/spinytech/macore/router/RouterRequestUtil.java @@ -0,0 +1,147 @@ +package com.spinytech.macore.router; + +import android.content.Context; +import android.text.TextUtils; + +import com.spinytech.macore.tools.Logger; +import com.spinytech.macore.tools.ProcessUtil; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.Iterator; + +/** + * Created by erfli on 2/17/17. + */ + +public class RouterRequestUtil { + static final String TAG = "RouterRequest"; + static final int length = 64; + public static volatile RouterRequest[] table = new RouterRequest[length]; + static final int RESET_NUM = 1000; + static volatile String DEFAULT_PROCESS = ""; + + static { + for (int i = 0; i < RouterRequestUtil.length; i++) { + RouterRequestUtil.table[i] = new RouterRequest(); + } + } + + public static RouterRequest json(String requestJsonString) { + RouterRequest routerRequest = new RouterRequest(); + try { + JSONObject jsonObject = new JSONObject(requestJsonString); + routerRequest.from = jsonObject.getString("from"); + routerRequest.domain = jsonObject.getString("domain"); + routerRequest.provider = jsonObject.getString("provider"); + routerRequest.action = jsonObject.getString("action"); + try { + JSONObject jsonData = new JSONObject(jsonObject.getString("data")); + Iterator it = jsonData.keys(); + while (it.hasNext()) { + String key = String.valueOf(it.next()); + String value = (String) jsonData.get(key); + routerRequest.data.put(key, value); + } + } catch (Exception e) { + e.printStackTrace(); + routerRequest.data = new HashMap<>(); + } + } catch (JSONException e) { + e.printStackTrace(); + } + return routerRequest; + } + + public static RouterRequest url(String url) { + RouterRequest routerRequest = new RouterRequest(); + int questIndex = url.indexOf('?'); + String[] urls = url.split("\\?"); + if (urls.length != 1 && urls.length != 2) { + Logger.e(TAG, "The url is illegal."); + return routerRequest; + } + String[] targets = urls[0].split("/"); + if (targets.length == 3) { + routerRequest.domain = targets[0]; + routerRequest.provider = targets[1]; + routerRequest.action = targets[2]; + } else { + Logger.e(TAG, "The url is illegal."); + return routerRequest; + } + //Add params + if (questIndex != -1) { + String queryString = urls[1]; + if (queryString != null && queryString.length() > 0) { + int ampersandIndex, lastAmpersandIndex = 0; + String subStr, key, value; + String[] paramPair, values, newValues; + do { + ampersandIndex = queryString.indexOf('&', lastAmpersandIndex) + 1; + if (ampersandIndex > 0) { + subStr = queryString.substring(lastAmpersandIndex, ampersandIndex - 1); + lastAmpersandIndex = ampersandIndex; + } else { + subStr = queryString.substring(lastAmpersandIndex); + } + paramPair = subStr.split("="); + key = paramPair[0]; + value = paramPair.length == 1 ? "" : paramPair[1]; + try { + value = URLDecoder.decode(value, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + routerRequest.data.put(key, value); + } while (ampersandIndex > 0); + } + } + return routerRequest; + } + + public static String getProcess(Context context) { + if (TextUtils.isEmpty(DEFAULT_PROCESS) || ProcessUtil.UNKNOWN_PROCESS_NAME.equals(DEFAULT_PROCESS)) { + DEFAULT_PROCESS = ProcessUtil.getProcessName(context, ProcessUtil.getMyProcessId()); + } + return DEFAULT_PROCESS; + } + + public static RouterRequest obtain(Context context) { + return obtain(context, 0); + } + + public static RouterRequest obtain(Context context, int retryTime) { + int index = RouterRequest.sIndex.getAndIncrement(); + if (index > RESET_NUM) { + RouterRequest.sIndex.compareAndSet(index, 0); + if (index > RESET_NUM * 2) { + RouterRequest.sIndex.set(0); + } + } + + int num = index & (length - 1); + + RouterRequest target = table[num]; + + if (target.isIdle.compareAndSet(true, false)) { + target.from = getProcess(context); + target.domain = getProcess(context); + target.provider = ""; + target.action = ""; + target.data.clear(); + return target; + } else { + if (retryTime < 5) { + return obtain(context, retryTime++); + } else { + return new RouterRequest(context); + } + + } + } +} diff --git a/macore/src/main/java/com/spinytech/macore/router/RouterResponse.java b/macore/src/main/java/com/spinytech/macore/router/RouterResponse.java deleted file mode 100644 index ad6e931..0000000 --- a/macore/src/main/java/com/spinytech/macore/router/RouterResponse.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.spinytech.macore.router; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -/** - * Created by wanglei on 2016/12/27. - */ - -public class RouterResponse { - - private static final int TIME_OUT = 30 * 1000; - - private long mTimeOut = 0; - private boolean mHasGet = false; - boolean mIsAsync = true; - - int mCode = -1; - - String mMessage = ""; - - String mData; - - Object mObject; - - /** - * This field is MaActionResult.toString() - */ - String mResultString; - - Future mAsyncResponse; - - public RouterResponse() { - this(TIME_OUT); - } - - public RouterResponse(long timeout) { - if (timeout > TIME_OUT * 2 || timeout < 0) { - timeout = TIME_OUT; - } - mTimeOut = timeout; - } - - public boolean isAsync() { - return mIsAsync; - } - - public String get() throws Exception { - if (mIsAsync) { - mResultString = mAsyncResponse.get(mTimeOut, TimeUnit.MILLISECONDS); - if (!mHasGet) { - try { - JSONObject jsonObject = new JSONObject(mResultString); - this.mCode = jsonObject.getInt("code"); - this.mMessage = jsonObject.getString("msg"); - this.mData = jsonObject.getString("data"); - } catch (JSONException e) { - e.printStackTrace(); - } - mHasGet = true; - } - } - return mResultString; - } - - public int getCode() throws Exception { - if (!mHasGet) { - get(); - } - return mCode; - } - - public String getMessage() throws Exception { - if (!mHasGet) { - get(); - } - return mMessage; - } - - public String getData() throws Exception { - if (!mHasGet) { - get(); - } - return mData; - } - - public Object getObject() throws Exception { - if (!mHasGet) { - get(); - } - return mObject; - } - -} diff --git a/macore/src/main/java/com/spinytech/macore/router/WideRouter.java b/macore/src/main/java/com/spinytech/macore/router/WideRouter.java index a019afb..2c96693 100644 --- a/macore/src/main/java/com/spinytech/macore/router/WideRouter.java +++ b/macore/src/main/java/com/spinytech/macore/router/WideRouter.java @@ -9,8 +9,6 @@ import android.support.annotation.NonNull; import android.text.TextUtils; -import com.spinytech.macore.ILocalRouterAIDL; -import com.spinytech.macore.MaActionResult; import com.spinytech.macore.MaApplication; import com.spinytech.macore.tools.Logger; import com.spinytech.macore.tools.ProcessUtil; @@ -170,7 +168,7 @@ public void run() { }).start(); } - boolean answerLocalAsync(String domain, String routerRequest) { + boolean answerLocalAsync(String domain, RouterRequest routerRequest) { ILocalRouterAIDL target = mLocalRouterAIDLMap.get(domain); if (target == null) { ConnectServiceWrapper connectServiceWrapper = sLocalRouterClasses.get(domain); @@ -193,27 +191,22 @@ boolean answerLocalAsync(String domain, String routerRequest) { } } - public RouterResponse route(String domain, String routerRequest) { - Logger.d(TAG, "Process:" + PROCESS_NAME + "\nWide route start: " + System.currentTimeMillis()); - RouterResponse routerResponse = new RouterResponse(); + public MaActionResult route(String domain, RouterRequest routerRequest) { + Logger.d(TAG, "Process:" + PROCESS_NAME + "\nWide rxRoute start: " + System.currentTimeMillis()); if (mIsStopping) { MaActionResult result = new MaActionResult.Builder() .code(MaActionResult.CODE_WIDE_STOPPING) .msg("Wide router is stopping.") .build(); - routerResponse.mIsAsync = true; - routerResponse.mResultString = result.toString(); - return routerResponse; + return result; } if (PROCESS_NAME.equals(domain)) { MaActionResult result = new MaActionResult.Builder() .code(MaActionResult.CODE_TARGET_IS_WIDE) .msg("Domain can not be " + PROCESS_NAME + ".") .build(); - routerResponse.mIsAsync = true; - routerResponse.mResultString = result.toString(); - return routerResponse; + return result; } ILocalRouterAIDL target = mLocalRouterAIDLMap.get(domain); if (null == target) { @@ -222,10 +215,8 @@ public RouterResponse route(String domain, String routerRequest) { .code(MaActionResult.CODE_ROUTER_NOT_REGISTER) .msg("The " + domain + " has not registered.") .build(); - routerResponse.mIsAsync = false; - routerResponse.mResultString = result.toString(); Logger.d(TAG, "Process:" + PROCESS_NAME + "\nLocal not register end: " + System.currentTimeMillis()); - return routerResponse; + return result; } else { // Wait to bind the target process connect service, timeout is 30s. Logger.d(TAG, "Process:" + PROCESS_NAME + "\nBind local router start: " + System.currentTimeMillis()); @@ -248,27 +239,24 @@ public RouterResponse route(String domain, String routerRequest) { .code(MaActionResult.CODE_CANNOT_BIND_LOCAL) .msg("Can not bind " + domain + ", time out.") .build(); - routerResponse.mResultString = result.toString(); - return routerResponse; + return result; } } } } try { Logger.d(TAG, "Process:" + PROCESS_NAME + "\nWide target start: " + System.currentTimeMillis()); - String resultString = target.route(routerRequest); - routerResponse.mResultString = resultString; - Logger.d(TAG, "Process:" + PROCESS_NAME + "\nWide route end: " + System.currentTimeMillis()); + MaActionResult maActionResult = target.route(routerRequest); + Logger.d(TAG, "Process:" + PROCESS_NAME + "\nWide rxRoute end: " + System.currentTimeMillis()); + return maActionResult; } catch (RemoteException e) { e.printStackTrace(); MaActionResult result = new MaActionResult.Builder() .code(MaActionResult.CODE_REMOTE_EXCEPTION) .msg(e.getMessage()) .build(); - routerResponse.mResultString = result.toString(); - return routerResponse; + return result; } - return routerResponse; } } diff --git a/macore/src/main/java/com/spinytech/macore/router/WideRouterConnectService.java b/macore/src/main/java/com/spinytech/macore/router/WideRouterConnectService.java index 9a7d24b..de55f58 100644 --- a/macore/src/main/java/com/spinytech/macore/router/WideRouterConnectService.java +++ b/macore/src/main/java/com/spinytech/macore/router/WideRouterConnectService.java @@ -6,8 +6,6 @@ import android.os.RemoteException; import android.support.annotation.Nullable; -import com.spinytech.macore.IWideRouterAIDL; -import com.spinytech.macore.MaActionResult; import com.spinytech.macore.MaApplication; import com.spinytech.macore.tools.Logger; @@ -66,25 +64,23 @@ public IBinder onBind(Intent intent) { IWideRouterAIDL.Stub stub = new IWideRouterAIDL.Stub() { @Override - public boolean checkResponseAsync(String domain, String routerRequest) throws RemoteException { + public boolean checkResponseAsync(String domain, RouterRequest routerRequest) throws RemoteException { return WideRouter.getInstance(MaApplication.getMaApplication()) .answerLocalAsync(domain, routerRequest); } @Override - public String route(String domain, String routerRequest) { + public MaActionResult route(String domain, RouterRequest routerRequest) { try { return WideRouter.getInstance(MaApplication.getMaApplication()) - .route(domain, routerRequest) - .mResultString; + .route(domain, routerRequest); } catch (Exception e) { e.printStackTrace(); return new MaActionResult.Builder() .code(MaActionResult.CODE_ERROR) .msg(e.getMessage()) - .build() - .toString(); + .build(); } } diff --git a/macore/src/main/java/com/spinytech/macore/tools/Logger.java b/macore/src/main/java/com/spinytech/macore/tools/Logger.java index 0accc37..c5b97ce 100644 --- a/macore/src/main/java/com/spinytech/macore/tools/Logger.java +++ b/macore/src/main/java/com/spinytech/macore/tools/Logger.java @@ -12,7 +12,7 @@ public class Logger { public final static int DEBUG = 4; public final static int VERBOSE = 5; - public static int LOG_LEVEL = ERROR; + public static int LOG_LEVEL = VERBOSE; public static void e(String tag, String msg) { diff --git a/maindemo/build.gradle b/maindemo/build.gradle index 550947b..64064c4 100644 --- a/maindemo/build.gradle +++ b/maindemo/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.application' +apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 24 @@ -23,15 +24,20 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) + compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:24.2.1' testCompile 'junit:junit:4.12' - compile project(':macore') + if (Local.toBoolean()){ + compile project(':macore') + apt project(':compile') + }else{ + apt 'com.github.wutongke.modularization:compile:1.1.1' + compile 'com.github.wutongke.modularization:macore:1.1.1' + } compile project(':musicdemo') compile project(':picdemo') compile project(':webdemo') - } diff --git a/maindemo/src/main/java/com/spinytech/maindemo/AsyncAction.java b/maindemo/src/main/java/com/spinytech/maindemo/AsyncAction.java index 4025014..f1040ac 100644 --- a/maindemo/src/main/java/com/spinytech/maindemo/AsyncAction.java +++ b/maindemo/src/main/java/com/spinytech/maindemo/AsyncAction.java @@ -4,43 +4,48 @@ import android.text.TextUtils; import android.util.Log; +import com.linked.annotion.Action; import com.spinytech.macore.MaAction; -import com.spinytech.macore.MaActionResult; - -import java.util.HashMap; +import com.spinytech.macore.router.MaActionResult; +import com.spinytech.macore.router.RouterRequest; /** * Created by wanglei on 2016/12/28. */ - -public class AsyncAction extends MaAction { +@Action(processName = "com.spinytech.maindemo", providerName = "main") +public class AsyncAction implements MaAction { @Override - public boolean isAsync(Context context, HashMap requestData) { + public boolean isAsync(Context context, RouterRequest requestData) { return true; } @Override - public MaActionResult invoke(Context context, HashMap requestData) { + public MaActionResult invoke(Context context, RouterRequest requestData) { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } String temp = ""; - if(!TextUtils.isEmpty(requestData.get("1"))){ - temp+=requestData.get("1"); + if (!TextUtils.isEmpty((String) requestData.getData().get("1"))) { + temp += requestData.getData().get("1"); } - if(!TextUtils.isEmpty(requestData.get("2"))){ - temp+=requestData.get("2"); + if (!TextUtils.isEmpty((CharSequence) requestData.getData().get("2"))) { + temp += requestData.getData().get("2"); } - Log.e("AsyncAction",temp); + Log.e("AsyncAction", temp); MaActionResult result = new MaActionResult.Builder() .code(MaActionResult.CODE_SUCCESS) .msg("success") .data(temp) - .object(null) + .result(null) .build(); return result; } + + @Override + public String getName() { + return "async"; + } } diff --git a/maindemo/src/main/java/com/spinytech/maindemo/MainActivity.java b/maindemo/src/main/java/com/spinytech/maindemo/MainActivity.java index 1b7f927..fd5c540 100644 --- a/maindemo/src/main/java/com/spinytech/maindemo/MainActivity.java +++ b/maindemo/src/main/java/com/spinytech/maindemo/MainActivity.java @@ -1,19 +1,21 @@ package com.spinytech.maindemo; import android.os.Bundle; -import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Toast; +import com.spinytech.macore.router.MaActionResult; import com.spinytech.macore.MaApplication; import com.spinytech.macore.router.LocalRouter; -import com.spinytech.macore.router.RouterRequest; -import com.spinytech.macore.router.RouterResponse; +import com.spinytech.macore.router.RouterRequestUtil; +import com.spinytech.macore.Song; -public class MainActivity extends AppCompatActivity { +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.functions.Consumer; +import io.reactivex.schedulers.Schedulers; - private Handler handler = new Handler(); +public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { @@ -23,48 +25,55 @@ protected void onCreate(Bundle savedInstanceState) { @Override public void onClick(View v) { try { - RouterResponse response = LocalRouter.getInstance(MaApplication.getMaApplication()) - .route(MainActivity.this, RouterRequest.obtain(MainActivity.this).provider("main") + LocalRouter.getInstance(MaApplication.getMaApplication()) + .rxRoute(MainActivity.this, RouterRequestUtil.obtain(MainActivity.this).provider("main") .action("sync") .data("1", "Hello") - .data("2", "World")); - Toast.makeText(MainActivity.this, response.get(), Toast.LENGTH_SHORT).show(); + .data("2", "World")) + .subscribeOn(Schedulers.from(ThreadPool.getThreadPoolSingleton())) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer() { + @Override + public void accept(MaActionResult maActionResult) throws Exception { + Toast.makeText(MainActivity.this, maActionResult.getMsg(), Toast.LENGTH_SHORT).show(); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show(); + } + }); + } catch (Exception e) { e.printStackTrace(); } } }); + findViewById(R.id.main_local_async_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { - final RouterResponse response = LocalRouter.getInstance(MaApplication.getMaApplication()) - .route(MainActivity.this, RouterRequest.obtain(MainActivity.this).provider("main") + LocalRouter.getInstance(MaApplication.getMaApplication()) + .rxRoute(MainActivity.this, RouterRequestUtil.obtain(MainActivity.this).provider("main") .action("async") .data("1", "Hello") - .data("2", "World")); - Toast.makeText(MainActivity.this, "please wait", Toast.LENGTH_SHORT).show(); - new Thread(new Runnable() { - @Override - public void run() { - try { - final String result = response.get(); - handler.post(new Runnable() { - @Override - public void run() { - try { - Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } catch (Exception e) { - e.printStackTrace(); - } + .data("2", "World")) + .subscribeOn(Schedulers.from(ThreadPool.getThreadPoolSingleton())) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer() { + @Override + public void accept(MaActionResult maActionResult) throws Exception { + Toast.makeText(MainActivity.this, maActionResult.getMsg(), Toast.LENGTH_SHORT).show(); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show(); + } + }); - } - }).start(); + Toast.makeText(MainActivity.this, "please wait", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } @@ -75,40 +84,27 @@ public void run() { findViewById(R.id.main_play_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - final long startTime = System.currentTimeMillis(); - final RouterRequest request = new RouterRequest.Builder(getApplicationContext()) - .domain("com.spinytech.maindemo:music") - .provider("music") - .action("play") - .build(); try { - final RouterResponse response = LocalRouter.getInstance(MaApplication.getMaApplication()) - .route(MainActivity.this, RouterRequest.obtain(MainActivity.this) + LocalRouter.getInstance(MaApplication.getMaApplication()) + .rxRoute(MainActivity.this, RouterRequestUtil.obtain(MainActivity.this) .domain("com.spinytech.maindemo:music") .provider("music") - .action("play")); - response.isAsync(); - new Thread(new Runnable() { - @Override - public void run() { - try { - final String temp = response.getData(); - final long time = System.currentTimeMillis() - startTime; - handler.post(new Runnable() { - @Override - public void run() { - try { - Toast.makeText(MainActivity.this, "async:" + response.isAsync() + " cost:" + time + " response:" + response.get(), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } catch (Exception e) { - e.printStackTrace(); - } - } - }).start(); + .action("play") + .reqeustObject(new Song("see you")) + ) + .subscribeOn(Schedulers.from(ThreadPool.getThreadPoolSingleton())) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer() { + @Override + public void accept(MaActionResult maActionResult) throws Exception { + Toast.makeText(MainActivity.this, maActionResult.getMsg(), Toast.LENGTH_SHORT).show(); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show(); + } + }); } catch (Exception e) { e.printStackTrace(); } @@ -117,35 +113,25 @@ public void run() { findViewById(R.id.main_stop_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - final long startTime = System.currentTimeMillis(); try { - final RouterResponse response = LocalRouter.getInstance(MaApplication.getMaApplication()) - .route(MainActivity.this, RouterRequest.obtain(MainActivity.this) + LocalRouter.getInstance(MaApplication.getMaApplication()) + .rxRoute(MainActivity.this, RouterRequestUtil.obtain(MainActivity.this) .domain("com.spinytech.maindemo:music") .provider("music") - .action("stop")); - response.isAsync(); - new Thread(new Runnable() { - @Override - public void run() { - try { - final String temp = response.getData(); - final long time = System.currentTimeMillis() - startTime; - handler.post(new Runnable() { - @Override - public void run() { - try { - Toast.makeText(MainActivity.this, "async:" + response.isAsync() + " cost:" + time + " response:" + response.get(), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } catch (Exception e) { - e.printStackTrace(); - } - } - }).start(); + .action("stop")) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.from(ThreadPool.getThreadPoolSingleton())) + .subscribe(new Consumer() { + @Override + public void accept(MaActionResult maActionResult) throws Exception { + Toast.makeText(MainActivity.this, maActionResult.getMsg(), Toast.LENGTH_SHORT).show(); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show(); + } + }); } catch (Exception e) { e.printStackTrace(); } @@ -156,35 +142,25 @@ public void run() { findViewById(R.id.main_music_shutdown_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - final long startTime = System.currentTimeMillis(); try { - final RouterResponse response = LocalRouter.getInstance(MaApplication.getMaApplication()) - .route(MainActivity.this, RouterRequest.obtain(MainActivity.this) + LocalRouter.getInstance(MaApplication.getMaApplication()) + .rxRoute(MainActivity.this, RouterRequestUtil.obtain(MainActivity.this) .domain("com.spinytech.maindemo:music") .provider("music") - .action("shutdown")); - response.isAsync(); - new Thread(new Runnable() { - @Override - public void run() { - try { - final String temp = response.getData(); - final long time = System.currentTimeMillis() - startTime; - handler.post(new Runnable() { - @Override - public void run() { - try { - Toast.makeText(MainActivity.this, "async:" + response.isAsync() + " cost:" + time + " response:" + response.get(), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } catch (Exception e) { - e.printStackTrace(); - } - } - }).start(); + .action("shutdown")) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.from(ThreadPool.getThreadPoolSingleton())) + .subscribe(new Consumer() { + @Override + public void accept(MaActionResult maActionResult) throws Exception { + Toast.makeText(MainActivity.this, maActionResult.getMsg(), Toast.LENGTH_SHORT).show(); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show(); + } + }); } catch (Exception e) { e.printStackTrace(); } @@ -199,36 +175,26 @@ public void onClick(View v) { findViewById(R.id.main_pic_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - final long startTime = System.currentTimeMillis(); try { - final RouterResponse response = LocalRouter.getInstance(MaApplication.getMaApplication()) - .route(MainActivity.this, RouterRequest.obtain(MainActivity.this) + LocalRouter.getInstance(MaApplication.getMaApplication()) + .rxRoute(MainActivity.this, RouterRequestUtil.obtain(MainActivity.this) .domain("com.spinytech.maindemo:pic") .provider("pic") .action("pic") - .data("is_big", "0")); - response.isAsync(); - new Thread(new Runnable() { - @Override - public void run() { - try { - final String temp = response.getData(); - final long time = System.currentTimeMillis() - startTime; - handler.post(new Runnable() { - @Override - public void run() { - try { - Toast.makeText(MainActivity.this, "async:" + response.isAsync() + " cost:" + time + " response:" + response.get(), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } catch (Exception e) { - e.printStackTrace(); - } - } - }).start(); + .data("is_big", "0")) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.from(ThreadPool.getThreadPoolSingleton())) + .subscribe(new Consumer() { + @Override + public void accept(MaActionResult maActionResult) throws Exception { + Toast.makeText(MainActivity.this, maActionResult.getMsg(), Toast.LENGTH_SHORT).show(); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show(); + } + }); } catch (Exception e) { e.printStackTrace(); } @@ -238,36 +204,26 @@ public void run() { findViewById(R.id.main_big_pic_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - final long startTime = System.currentTimeMillis(); try { - final RouterResponse response = LocalRouter.getInstance(MaApplication.getMaApplication()) - .route(MainActivity.this, RouterRequest.obtain(MainActivity.this) + LocalRouter.getInstance(MaApplication.getMaApplication()) + .rxRoute(MainActivity.this, RouterRequestUtil.obtain(MainActivity.this) .domain("com.spinytech.maindemo:pic") .provider("pic") .action("pic") - .data("is_big", "1")); - response.isAsync(); - new Thread(new Runnable() { - @Override - public void run() { - try { - final String temp = response.getData(); - final long time = System.currentTimeMillis() - startTime; - handler.post(new Runnable() { - @Override - public void run() { - try { - Toast.makeText(MainActivity.this, "async:" + response.isAsync() + " cost:" + time + " response:" + response.get(), Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } catch (Exception e) { - e.printStackTrace(); - } - } - }).start(); + .data("is_big", "1")) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.from(ThreadPool.getThreadPoolSingleton())) + .subscribe(new Consumer() { + @Override + public void accept(MaActionResult maActionResult) throws Exception { + Toast.makeText(MainActivity.this, maActionResult.getMsg(), Toast.LENGTH_SHORT).show(); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show(); + } + }); } catch (Exception e) { e.printStackTrace(); } @@ -278,7 +234,7 @@ public void run() { public void onClick(View v) { try { LocalRouter.getInstance(MaApplication.getMaApplication()) - .route(MainActivity.this, RouterRequest.obtain(MainActivity.this) + .rxRoute(MainActivity.this, RouterRequestUtil.obtain(MainActivity.this) .provider("web") .action("web") ); @@ -287,6 +243,7 @@ public void onClick(View v) { } } }); + } } diff --git a/maindemo/src/main/java/com/spinytech/maindemo/MainApplicationLogic.java b/maindemo/src/main/java/com/spinytech/maindemo/MainApplicationLogic.java index 3056ca6..61b2a03 100644 --- a/maindemo/src/main/java/com/spinytech/maindemo/MainApplicationLogic.java +++ b/maindemo/src/main/java/com/spinytech/maindemo/MainApplicationLogic.java @@ -11,6 +11,5 @@ public class MainApplicationLogic extends BaseApplicationLogic { @Override public void onCreate() { super.onCreate(); - LocalRouter.getInstance(mApplication).registerProvider("main",new MainProvider()); } } diff --git a/maindemo/src/main/java/com/spinytech/maindemo/MainProvider.java b/maindemo/src/main/java/com/spinytech/maindemo/MainProvider.java index c845a95..560a563 100644 --- a/maindemo/src/main/java/com/spinytech/maindemo/MainProvider.java +++ b/maindemo/src/main/java/com/spinytech/maindemo/MainProvider.java @@ -1,15 +1,15 @@ package com.spinytech.maindemo; +import com.linked.annotion.Provider; import com.spinytech.macore.MaProvider; /** * Created by wanglei on 2016/12/28. */ - +@Provider(processName = "com.spinytech.maindemo") public class MainProvider extends MaProvider { @Override - protected void registerActions() { - registerAction("sync",new SyncAction()); - registerAction("async",new AsyncAction()); + protected String getName() { + return "main"; } } diff --git a/maindemo/src/main/java/com/spinytech/maindemo/MyApplication.java b/maindemo/src/main/java/com/spinytech/maindemo/MyApplication.java index 01765cb..78da7f6 100644 --- a/maindemo/src/main/java/com/spinytech/maindemo/MyApplication.java +++ b/maindemo/src/main/java/com/spinytech/maindemo/MyApplication.java @@ -1,5 +1,6 @@ package com.spinytech.maindemo; +import com.linked.annotion.Modules; import com.spinytech.macore.MaApplication; import com.spinytech.macore.router.WideRouter; import com.spinytech.musicdemo.MusicApplicationLogic; @@ -11,7 +12,7 @@ /** * Created by wanglei on 2016/11/29. */ - +@Modules(modules = {"music","pic","web"}) public class MyApplication extends MaApplication { @Override public void initializeAllProcessRouter() { diff --git a/maindemo/src/main/java/com/spinytech/maindemo/SyncAction.java b/maindemo/src/main/java/com/spinytech/maindemo/SyncAction.java index de9ed17..519003f 100644 --- a/maindemo/src/main/java/com/spinytech/maindemo/SyncAction.java +++ b/maindemo/src/main/java/com/spinytech/maindemo/SyncAction.java @@ -4,38 +4,43 @@ import android.text.TextUtils; import android.widget.Toast; +import com.linked.annotion.Action; import com.spinytech.macore.MaAction; -import com.spinytech.macore.MaActionResult; - -import java.util.HashMap; +import com.spinytech.macore.router.MaActionResult; +import com.spinytech.macore.router.RouterRequest; /** * Created by wanglei on 2016/12/28. */ - -public class SyncAction extends MaAction { +@Action(processName = "com.spinytech.maindemo", providerName = "main") +public class SyncAction implements MaAction { @Override - public boolean isAsync(Context context, HashMap requestData) { + public boolean isAsync(Context context, RouterRequest requestData) { return false; } @Override - public MaActionResult invoke(Context context, HashMap requestData) { + public MaActionResult invoke(Context context, RouterRequest requestData) { String temp = ""; - if(!TextUtils.isEmpty(requestData.get("1"))){ - temp+=requestData.get("1"); + if(!TextUtils.isEmpty((CharSequence) requestData.getData().get("1"))){ + temp+=requestData.getData().get("1"); } - if(!TextUtils.isEmpty(requestData.get("2"))){ - temp+=requestData.get("2"); + if(!TextUtils.isEmpty((CharSequence) requestData.getData().get("2"))){ + temp+=requestData.getData().get("2"); } Toast.makeText(context, "SyncAction.invoke:"+temp, Toast.LENGTH_SHORT).show(); MaActionResult result = new MaActionResult.Builder() .code(MaActionResult.CODE_SUCCESS) .msg("success") .data(temp) - .object(null) + .result(null) .build(); return result; } + + @Override + public String getName() { + return "sync"; + } } diff --git a/maindemo/src/main/java/com/spinytech/maindemo/ThreadPool.java b/maindemo/src/main/java/com/spinytech/maindemo/ThreadPool.java new file mode 100644 index 0000000..df301d2 --- /dev/null +++ b/maindemo/src/main/java/com/spinytech/maindemo/ThreadPool.java @@ -0,0 +1,20 @@ +package com.spinytech.maindemo; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Created by erfli on 2/16/17. + */ + +public class ThreadPool { + private static ExecutorService executorService; + public static ExecutorService getThreadPoolSingleton(){ + if(executorService == null){ + synchronized (ThreadPool.class){ + executorService = Executors.newFixedThreadPool(3); + } + } + return executorService; + } +} diff --git a/musicdemo/build.gradle b/musicdemo/build.gradle index 7e56760..d8e0929 100644 --- a/musicdemo/build.gradle +++ b/musicdemo/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.library' +apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 24 @@ -28,5 +29,11 @@ dependencies { }) compile 'com.android.support:appcompat-v7:24.2.1' testCompile 'junit:junit:4.12' - compile project(':macore') + if (Local.toBoolean()){ + compile project(':macore') + apt project(':compile') + }else{ + apt 'com.github.wutongke.modularization:compile:1.1.1' + compile 'com.github.wutongke.modularization:macore:1.1.1' + } } diff --git a/musicdemo/src/main/java/com/spinytech/musicdemo/MusicApplicationLogic.java b/musicdemo/src/main/java/com/spinytech/musicdemo/MusicApplicationLogic.java index 63bb2b5..4008cb2 100644 --- a/musicdemo/src/main/java/com/spinytech/musicdemo/MusicApplicationLogic.java +++ b/musicdemo/src/main/java/com/spinytech/musicdemo/MusicApplicationLogic.java @@ -1,16 +1,19 @@ package com.spinytech.musicdemo; +import android.widget.Toast; + +import com.linked.annotion.Module; import com.spinytech.macore.multiprocess.BaseApplicationLogic; import com.spinytech.macore.router.LocalRouter; /** * Created by wanglei on 2016/11/30. */ - +@Module(name = "music") public class MusicApplicationLogic extends BaseApplicationLogic { @Override public void onCreate() { super.onCreate(); - LocalRouter.getInstance(mApplication).registerProvider("music",new MusicProvider()); + Toast.makeText(mApplication, "MusicApplicationLogic onCreate", Toast.LENGTH_SHORT).show(); } } diff --git a/musicdemo/src/main/java/com/spinytech/musicdemo/MusicProvider.java b/musicdemo/src/main/java/com/spinytech/musicdemo/MusicProvider.java index 96cd006..7ae3bbc 100644 --- a/musicdemo/src/main/java/com/spinytech/musicdemo/MusicProvider.java +++ b/musicdemo/src/main/java/com/spinytech/musicdemo/MusicProvider.java @@ -1,16 +1,15 @@ package com.spinytech.musicdemo; +import com.linked.annotion.Provider; import com.spinytech.macore.MaProvider; /** * Created by wanglei on 2016/12/28. */ - +@Provider(processName = "com.spinytech.maindemo:music") public class MusicProvider extends MaProvider{ @Override - protected void registerActions() { - registerAction("play",new PlayAction()); - registerAction("stop",new StopAction()); - registerAction("shutdown",new ShutdownAction()); + protected String getName() { + return "music"; } } diff --git a/musicdemo/src/main/java/com/spinytech/musicdemo/PlayAction.java b/musicdemo/src/main/java/com/spinytech/musicdemo/PlayAction.java index e8aa951..c74fa0a 100644 --- a/musicdemo/src/main/java/com/spinytech/musicdemo/PlayAction.java +++ b/musicdemo/src/main/java/com/spinytech/musicdemo/PlayAction.java @@ -2,34 +2,52 @@ import android.content.Context; import android.content.Intent; +import android.os.Handler; +import android.widget.Toast; +import com.linked.annotion.Action; import com.spinytech.macore.MaAction; -import com.spinytech.macore.MaActionResult; - -import java.util.HashMap; +import com.spinytech.macore.Song; +import com.spinytech.macore.router.MaActionResult; +import com.spinytech.macore.router.RouterRequest; +import com.spinytech.macore.tools.Logger; /** * Created by wanglei on 2016/12/28. */ - -public class PlayAction extends MaAction { +@Action(processName = "com.spinytech.maindemo:music", providerName = "music") +public class PlayAction implements MaAction { @Override - public boolean isAsync(Context context, HashMap requestData) { + public boolean isAsync(Context context, RouterRequest requestData) { return false; } @Override - public MaActionResult invoke(Context context, HashMap requestData) { - Intent intent = new Intent(context,MusicService.class); - intent.putExtra("command","play"); + public MaActionResult invoke(final Context context, final RouterRequest requestData) { + Intent intent = new Intent(context, MusicService.class); + intent.putExtra("command", "play"); context.startService(intent); MaActionResult result = new MaActionResult.Builder() .code(MaActionResult.CODE_SUCCESS) .msg("play success") - .data("") - .object(null) + .result(new Song("lili")) .build(); + Handler handler = new Handler(context.getMainLooper()); + handler.post(new Runnable() { + @Override + public void run() { + if (requestData != null && requestData.getRequestObject() != null) { + Toast.makeText(context, "歌曲名字:" + requestData.getRequestObject().name + "(并不知道)", Toast.LENGTH_SHORT).show(); + } + } + }); + Logger.d("com.spinytech", requestData.getRequestObject().name); return result; } + + @Override + public String getName() { + return "play"; + } } diff --git a/musicdemo/src/main/java/com/spinytech/musicdemo/ShutdownAction.java b/musicdemo/src/main/java/com/spinytech/musicdemo/ShutdownAction.java index 4dd51da..d4bce35 100644 --- a/musicdemo/src/main/java/com/spinytech/musicdemo/ShutdownAction.java +++ b/musicdemo/src/main/java/com/spinytech/musicdemo/ShutdownAction.java @@ -4,31 +4,31 @@ import android.content.Intent; import android.util.Log; +import com.linked.annotion.Action; import com.spinytech.macore.MaAction; -import com.spinytech.macore.MaActionResult; +import com.spinytech.macore.router.MaActionResult; import com.spinytech.macore.MaApplication; import com.spinytech.macore.router.LocalRouter; - -import java.util.HashMap; +import com.spinytech.macore.router.RouterRequest; /** * Created by wanglei on 2016/12/28. */ - -public class ShutdownAction extends MaAction { +@Action(processName = "com.spinytech.maindemo:music", providerName = "music") +public class ShutdownAction implements MaAction { @Override - public boolean isAsync(Context context, HashMap requestData) { + public boolean isAsync(Context context, RouterRequest requestData) { return true; } @Override - public MaActionResult invoke(Context context, HashMap requestData) { + public MaActionResult invoke(Context context, RouterRequest requestData) { MaActionResult result = new MaActionResult.Builder() .code(MaActionResult.CODE_SUCCESS) .msg("success") .data("") - .object(null) + .result(null) .build(); context.getApplicationContext().stopService(new Intent(context,MusicService.class)); @@ -47,4 +47,9 @@ public void run() { }).start(); return result; } + + @Override + public String getName() { + return "shutdown"; + } } diff --git a/musicdemo/src/main/java/com/spinytech/musicdemo/StopAction.java b/musicdemo/src/main/java/com/spinytech/musicdemo/StopAction.java index a450b87..61d4ebd 100644 --- a/musicdemo/src/main/java/com/spinytech/musicdemo/StopAction.java +++ b/musicdemo/src/main/java/com/spinytech/musicdemo/StopAction.java @@ -3,25 +3,25 @@ import android.content.Context; import android.content.Intent; +import com.linked.annotion.Action; import com.spinytech.macore.MaAction; -import com.spinytech.macore.MaActionResult; +import com.spinytech.macore.router.MaActionResult; +import com.spinytech.macore.router.RouterRequest; import com.spinytech.macore.tools.Logger; -import java.util.HashMap; - /** * Created by wanglei on 2016/12/28. */ - -public class StopAction extends MaAction { +@Action(processName = "com.spinytech.maindemo:music", providerName = "music") +public class StopAction implements MaAction { @Override - public boolean isAsync(Context context, HashMap requestData) { + public boolean isAsync(Context context, RouterRequest requestData) { return false; } @Override - public MaActionResult invoke(Context context, HashMap requestData) { + public MaActionResult invoke(Context context, RouterRequest requestData) { Intent intent = new Intent(context, MusicService.class); intent.putExtra("command", "stop"); context.startService(intent); @@ -29,10 +29,15 @@ public MaActionResult invoke(Context context, HashMap requestDat .code(MaActionResult.CODE_SUCCESS) .msg("stop success") .data("") - .object(null) + .result(null) .build(); Logger.d("StopAction", "\nStopAction end: " + System.currentTimeMillis()); return result; } + + @Override + public String getName() { + return "stop"; + } } diff --git a/picdemo/build.gradle b/picdemo/build.gradle index b2461be..d4d8e85 100644 --- a/picdemo/build.gradle +++ b/picdemo/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.library' +apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 25 @@ -28,5 +29,11 @@ dependencies { }) compile 'com.android.support:appcompat-v7:25.1.0' testCompile 'junit:junit:4.12' - compile project(':macore') + if (Local.toBoolean()){ + compile project(':macore') + apt project(':compile') + }else{ + apt 'com.github.wutongke.modularization:compile:1.1.1' + compile 'com.github.wutongke.modularization:macore:1.1.1' + } } diff --git a/picdemo/src/main/java/com/spinytech/picdemo/Date.java b/picdemo/src/main/java/com/spinytech/picdemo/Date.java new file mode 100644 index 0000000..67507e8 --- /dev/null +++ b/picdemo/src/main/java/com/spinytech/picdemo/Date.java @@ -0,0 +1,42 @@ +package com.spinytech.picdemo; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Created by erfli on 2/16/17. + */ + +public class Date implements Parcelable { + String date; + + public Date() { + date = new java.util.Date().toString(); + } + + protected Date(Parcel in) { + date = in.readString(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Date createFromParcel(Parcel in) { + return new Date(in); + } + + @Override + public Date[] newArray(int size) { + return new Date[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(date); + } +} diff --git a/picdemo/src/main/java/com/spinytech/picdemo/PicAction.java b/picdemo/src/main/java/com/spinytech/picdemo/PicAction.java index 8fe9b8a..636aac7 100644 --- a/picdemo/src/main/java/com/spinytech/picdemo/PicAction.java +++ b/picdemo/src/main/java/com/spinytech/picdemo/PicAction.java @@ -4,24 +4,24 @@ import android.content.Context; import android.content.Intent; +import com.linked.annotion.Action; import com.spinytech.macore.MaAction; -import com.spinytech.macore.MaActionResult; - -import java.util.HashMap; +import com.spinytech.macore.router.MaActionResult; +import com.spinytech.macore.router.RouterRequest; /** * Created by wanglei on 2017/1/4. */ - -public class PicAction extends MaAction { +@Action(processName = "com.spinytech.maindemo:pic", providerName = "pic") +public class PicAction implements MaAction { @Override - public boolean isAsync(Context context, HashMap requestData) { + public boolean isAsync(Context context, RouterRequest requestData) { return false; } @Override - public MaActionResult invoke(Context context, HashMap requestData) { - String isBigString = requestData.get("is_big"); + public MaActionResult invoke(Context context, RouterRequest requestData) { + String isBigString = (String) requestData.getData().get("is_big"); boolean isBig = "1".equals(isBigString); if(context instanceof Activity){ Intent i = new Intent(context, PicActivity.class); @@ -33,6 +33,11 @@ public MaActionResult invoke(Context context, HashMap requestDat i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); } - return new MaActionResult.Builder().code(MaActionResult.CODE_SUCCESS).msg("success").data("").build(); + return new MaActionResult.Builder().code(MaActionResult.CODE_SUCCESS).msg("success").data("").result(new Date()).build(); + } + + @Override + public String getName() { + return "pic"; } } diff --git a/picdemo/src/main/java/com/spinytech/picdemo/PicApplicationLogic.java b/picdemo/src/main/java/com/spinytech/picdemo/PicApplicationLogic.java index 6820c03..dabca1f 100644 --- a/picdemo/src/main/java/com/spinytech/picdemo/PicApplicationLogic.java +++ b/picdemo/src/main/java/com/spinytech/picdemo/PicApplicationLogic.java @@ -1,17 +1,20 @@ package com.spinytech.picdemo; +import android.widget.Toast; + +import com.linked.annotion.Module; import com.spinytech.macore.multiprocess.BaseApplicationLogic; import com.spinytech.macore.router.LocalRouter; /** * Created by wanglei on 2017/1/4. */ - +@Module(name = "pic") public class PicApplicationLogic extends BaseApplicationLogic { @Override public void onCreate() { super.onCreate(); - LocalRouter.getInstance(mApplication).registerProvider("pic",new PicProvider()); + Toast.makeText(mApplication, "Pic_Process on Create", Toast.LENGTH_SHORT).show(); } } diff --git a/picdemo/src/main/java/com/spinytech/picdemo/PicProvider.java b/picdemo/src/main/java/com/spinytech/picdemo/PicProvider.java index d092d06..c388a00 100644 --- a/picdemo/src/main/java/com/spinytech/picdemo/PicProvider.java +++ b/picdemo/src/main/java/com/spinytech/picdemo/PicProvider.java @@ -1,14 +1,15 @@ package com.spinytech.picdemo; +import com.linked.annotion.Provider; import com.spinytech.macore.MaProvider; /** * Created by wanglei on 2017/1/4. */ - +@Provider(processName = "com.spinytech.maindemo:pic") public class PicProvider extends MaProvider{ @Override - protected void registerActions() { - registerAction("pic",new PicAction()); + protected String getName() { + return "pic"; } } diff --git a/settings.gradle b/settings.gradle index bc63f52..6b183e9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':macore', ':musicdemo', ':maindemo', ':picdemo', ':webdemo' +include ':macore', ':musicdemo', ':maindemo', ':picdemo', ':webdemo', ':compile', ':stub', ':annotation' diff --git a/stub/.gitignore b/stub/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/stub/.gitignore @@ -0,0 +1 @@ +/build diff --git a/stub/build.gradle b/stub/build.gradle new file mode 100644 index 0000000..49df001 --- /dev/null +++ b/stub/build.gradle @@ -0,0 +1,8 @@ +apply plugin: 'java' + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) +} + +sourceCompatibility = "1.7" +targetCompatibility = "1.7" diff --git a/stub/src/main/java/com/provider/ProviderInit.java b/stub/src/main/java/com/provider/ProviderInit.java new file mode 100644 index 0000000..01cf9ec --- /dev/null +++ b/stub/src/main/java/com/provider/ProviderInit.java @@ -0,0 +1,9 @@ +package com.provider; + +import java.util.HashMap; + +public class ProviderInit { + public static void init(HashMap providerMap, HashMap actionMap){ + + } +} diff --git a/webdemo/build.gradle b/webdemo/build.gradle index b2461be..f2cd618 100644 --- a/webdemo/build.gradle +++ b/webdemo/build.gradle @@ -1,5 +1,5 @@ apply plugin: 'com.android.library' - +apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 25 buildToolsVersion "25.0.0" @@ -28,5 +28,11 @@ dependencies { }) compile 'com.android.support:appcompat-v7:25.1.0' testCompile 'junit:junit:4.12' - compile project(':macore') + if (Local.toBoolean()){ + compile project(':macore') + apt project(':compile') + }else{ + apt 'com.github.wutongke.modularization:compile:1.1.1' + compile 'com.github.wutongke.modularization:macore:1.1.1' + } } diff --git a/webdemo/src/main/assets/page.html b/webdemo/src/main/assets/page.html index 1035bcc..9942806 100644 --- a/webdemo/src/main/assets/page.html +++ b/webdemo/src/main/assets/page.html @@ -7,13 +7,15 @@
-

LOCAL SYNC

+

LOCAL SYNC


-

PLAY MUSIC

+

PLAY MUSIC


-

STOP MUSIC

+

STOP MUSIC


-

OPEN PIC

+

OPEN PIC

+
+

OPEN 百度


\ No newline at end of file diff --git a/webdemo/src/main/java/com/spinytech/webdemo/WebAction.java b/webdemo/src/main/java/com/spinytech/webdemo/WebAction.java index b8d1085..26a20f5 100644 --- a/webdemo/src/main/java/com/spinytech/webdemo/WebAction.java +++ b/webdemo/src/main/java/com/spinytech/webdemo/WebAction.java @@ -4,23 +4,23 @@ import android.content.Context; import android.content.Intent; +import com.linked.annotion.Action; import com.spinytech.macore.MaAction; -import com.spinytech.macore.MaActionResult; - -import java.util.HashMap; +import com.spinytech.macore.router.MaActionResult; +import com.spinytech.macore.router.RouterRequest; /** * Created by wanglei on 2017/1/4. */ - -public class WebAction extends MaAction { +@Action(processName = "com.spinytech.maindemo", providerName = "web") +public class WebAction implements MaAction { @Override - public boolean isAsync(Context context, HashMap requestData) { + public boolean isAsync(Context context, RouterRequest requestData) { return false; } @Override - public MaActionResult invoke(Context context, HashMap requestData) { + public MaActionResult invoke(Context context, RouterRequest requestData) { if(context instanceof Activity){ Intent i = new Intent(context, WebActivity.class); context.startActivity(i); @@ -31,4 +31,9 @@ public MaActionResult invoke(Context context, HashMap requestDat } return new MaActionResult.Builder().code(MaActionResult.CODE_SUCCESS).msg("success").data("").build(); } + + @Override + public String getName() { + return "web"; + } } diff --git a/webdemo/src/main/java/com/spinytech/webdemo/WebActivity.java b/webdemo/src/main/java/com/spinytech/webdemo/WebActivity.java index f351cfb..ca76b77 100644 --- a/webdemo/src/main/java/com/spinytech/webdemo/WebActivity.java +++ b/webdemo/src/main/java/com/spinytech/webdemo/WebActivity.java @@ -9,11 +9,12 @@ import com.spinytech.macore.MaApplication; import com.spinytech.macore.router.LocalRouter; -import com.spinytech.macore.router.RouterRequest; +import com.spinytech.macore.router.RouterRequestUtil; public class WebActivity extends AppCompatActivity { private WebView mContentWv; + private static String protocole = "wutongke://"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -32,10 +33,10 @@ protected void onCreate(Bundle savedInstanceState) { public void dispatchAction(String url) { - if (url.indexOf("your_protocol://") >= 0) { - String command = url.substring("your_protocol://".length()); + if (url.indexOf(protocole) >= 0) { + String command = url.substring(protocole.length()); try { - LocalRouter.getInstance(MaApplication.getMaApplication()).route(this, new RouterRequest.Builder(this).url(command).build()); + LocalRouter.getInstance(MaApplication.getMaApplication()).rxRoute(this, RouterRequestUtil.url(command)); } catch (Exception e) { e.printStackTrace(); } @@ -45,7 +46,7 @@ public void dispatchAction(String url) { class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (!TextUtils.isEmpty(url) && url.startsWith("your_protocol://")) { + if (!TextUtils.isEmpty(url) && url.startsWith(protocole)) { dispatchAction(url); } else { mContentWv.loadUrl(url); diff --git a/webdemo/src/main/java/com/spinytech/webdemo/WebApplicationLogic.java b/webdemo/src/main/java/com/spinytech/webdemo/WebApplicationLogic.java index a9f46c4..f058d67 100644 --- a/webdemo/src/main/java/com/spinytech/webdemo/WebApplicationLogic.java +++ b/webdemo/src/main/java/com/spinytech/webdemo/WebApplicationLogic.java @@ -1,17 +1,19 @@ package com.spinytech.webdemo; +import android.widget.Toast; + +import com.linked.annotion.Module; import com.spinytech.macore.multiprocess.BaseApplicationLogic; -import com.spinytech.macore.router.LocalRouter; /** * Created by wanglei on 2017/1/4. */ - +@Module(name = "web") public class WebApplicationLogic extends BaseApplicationLogic { @Override public void onCreate() { super.onCreate(); - LocalRouter.getInstance(mApplication).registerProvider("web",new WebProvider()); + Toast.makeText(mApplication, "WebApplicationLogic onCreate", Toast.LENGTH_SHORT).show(); } } diff --git a/webdemo/src/main/java/com/spinytech/webdemo/WebProvider.java b/webdemo/src/main/java/com/spinytech/webdemo/WebProvider.java index beafcf3..104a6d9 100644 --- a/webdemo/src/main/java/com/spinytech/webdemo/WebProvider.java +++ b/webdemo/src/main/java/com/spinytech/webdemo/WebProvider.java @@ -1,14 +1,15 @@ package com.spinytech.webdemo; +import com.linked.annotion.Provider; import com.spinytech.macore.MaProvider; /** * Created by wanglei on 2017/1/4. */ - +@Provider(processName = "com.spinytech.maindemo") public class WebProvider extends MaProvider{ @Override - protected void registerActions() { - registerAction("web",new WebAction()); + protected String getName() { + return "web"; } }