├── .gitignore ├── AppSwitcherAndUpdate.bat ├── AppSwitcherAndUpdate.py ├── AppSwitcherConfig.txt ├── Dilutions ├── android.gradle ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── linhonghong │ │ └── dilutions │ │ ├── ActivityDilutionsManager.java │ │ ├── Dilutions.java │ │ ├── DilutionsBuilder.java │ │ ├── DilutionsFunction.java │ │ ├── DilutionsInstrument.java │ │ ├── DilutionsManager.java │ │ ├── DilutionsValue.java │ │ ├── FieldHanlder.java │ │ ├── HttpProtocolManager.java │ │ ├── ParameterHanlder.java │ │ ├── ProtocolManager.java │ │ ├── annotations │ │ ├── ActivityExtra.java │ │ ├── ActivityProtocol.java │ │ ├── ActivityProtocolExtra.java │ │ ├── ActivityProtocolPath.java │ │ ├── CustomAnimation.java │ │ ├── ExtraParam.java │ │ ├── FragmentArg.java │ │ ├── MethodExtra.java │ │ ├── MethodParam.java │ │ ├── MethodProtocol.java │ │ ├── Param.java │ │ ├── PassNull.java │ │ ├── ProtocolFrom.java │ │ └── ProtocolPath.java │ │ ├── data │ │ ├── DilutionsConfig.java │ │ ├── DilutionsConfigFactory.java │ │ ├── DilutionsData.java │ │ ├── DilutionsGlobalListener.java │ │ └── DilutionsMethodData.java │ │ ├── interfaces │ │ ├── DilutionsCallBack.java │ │ ├── DilutionsInterceptor.java │ │ └── DilutionsPathInterceptor.java │ │ └── utils │ │ ├── Checker.java │ │ ├── DilutionsUriBuilder.java │ │ └── DilutionsUtil.java │ └── res │ └── values │ └── strings.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── uiInterpreter.conf │ ├── java │ └── com │ │ └── linhonghong │ │ └── demo │ │ └── dilutions │ │ ├── Application.java │ │ ├── DebugService.java │ │ ├── MainActivity.java │ │ ├── Method.java │ │ ├── Test.java │ │ ├── TestAno.java │ │ └── TestObj.java │ └── res │ ├── anim │ ├── enter.xml │ └── exit.xml │ ├── layout │ └── activity_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── dilutionsPlugin ├── .gitignore ├── build.gradle ├── gradle.properties ├── p.gradle ├── proguard-rules.pro └── src │ └── main │ ├── groovy │ └── com.linhonghong.dilutions.plugin │ │ └── PluginImpl.groovy │ ├── java │ └── com │ │ └── linhonghong │ │ └── dilutions │ │ ├── BlackhandClassVisitor.java │ │ ├── BlackhandMethodInfo.java │ │ ├── DilutionsMetasWriter.java │ │ ├── DilutionsUtils.java │ │ ├── MethodAnnotationsInfo.java │ │ └── annotations │ │ ├── ActivityExtra.java │ │ ├── ActivityProtocol.java │ │ ├── ActivityProtocolExtra.java │ │ ├── ActivityProtocolPath.java │ │ ├── CustomAnimation.java │ │ ├── ExtraParam.java │ │ ├── FragmentArg.java │ │ ├── MethodExtra.java │ │ ├── MethodParam.java │ │ ├── MethodProtocol.java │ │ ├── Param.java │ │ ├── PassNull.java │ │ ├── ProtocolFrom.java │ │ └── ProtocolPath.java │ └── resources │ └── META-INF │ └── gradle-plugins │ └── dilutions.properties ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── pic.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | /captures 2 | /app/app.iml 3 | /app/build 4 | /.idea 5 | /build 6 | /Dilutions/build 7 | /Dilutions/Dilutions.iml 8 | /dilutionsPlugin/build 9 | /dilutionsPlugin/dilutionsPlugin.iml 10 | DilutionsProject.iml 11 | local.properties 12 | /.gradle -------------------------------------------------------------------------------- /AppSwitcherAndUpdate.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | start python AppSwitcherAndUpdate.py 3 | -------------------------------------------------------------------------------- /AppSwitcherAndUpdate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # coding=utf-8 3 | import zipfile 4 | import shutil 5 | import os 6 | import shlex 7 | import subprocess 8 | import time 9 | import re 10 | #获取当前路径 11 | currentDir = os.getcwd() 12 | #print("-->当前目录%s" % currentDir) 13 | #分支是否已经存在本地 14 | def isBranchExist(branchname): 15 | cmd = "git branch" 16 | r = os.popen(cmd) 17 | result = r.read() 18 | r.close() 19 | if branchname in result: 20 | return True 21 | else: 22 | return False 23 | #执行cmd命令 24 | def execCmd(cmd): 25 | r = os.popen(cmd) 26 | text = r.read() 27 | r.close() 28 | return text 29 | #init git 30 | exist = os.path.exists(".git") 31 | if exist==False: 32 | os.system("git init") 33 | print("--->git init") 34 | else: 35 | print("--->已初始化git") 36 | 37 | #Open file 38 | channel_file = 'AppSwitcherConfig.txt' 39 | print("---->open AppSwitcherConfig.txt") 40 | f = open(channel_file) 41 | #lines = f.readlines() 42 | for line in f: 43 | #print("----->行内容:%s"%line) 44 | array = line.split(";") 45 | project_address = array[0] 46 | project_name=array[1] 47 | branch_name=array[2] 48 | branch_name = branch_name.strip() 49 | gitIntoPath = currentDir+"/"+project_name 50 | print("======================>"+project_name+" branch to %s" % branch_name) 51 | if project_address.find("#",0,len(project_address))!=-1: 52 | print("##################忽略注释:"+project_address) 53 | elif os.path.exists(gitIntoPath)==False: 54 | #进入子目录 55 | os.makedirs(gitIntoPath) 56 | #git clone into 57 | execCmd("git clone "+project_address+" "+gitIntoPath) 58 | #cd dir 59 | os.chdir(gitIntoPath) 60 | if branch_name.strip()!='' and branch_name.find("master",0,len(branch_name))==-1 and branch_name.find("tag:",0,len(branch_name))==-1: 61 | #switch branch 62 | execCmd("git checkout --track "+" origin/"+branch_name) 63 | execCmd("git pull") 64 | elif branch_name.strip()!='' and branch_name.find("tag:",0,len(branch_name))!=-1: 65 | #switch tag 66 | arrayTag = branch_name.split(":") 67 | branchtagname=arrayTag[1]+"-from-tags" 68 | #if branchname exists 69 | isExistBranchAtLocal=isBranchExist(branchtagname) 70 | if isExistBranchAtLocal is False: 71 | execCmd("git checkout "+arrayTag[1]) 72 | execCmd("git checkout -b "+branchtagname) 73 | execCmd("git push origin "+branchtagname) 74 | execCmd("git branch --set-upstream-to=origin/"+branchtagname+" "+branchtagname) 75 | else: 76 | print("##################tag 本地已存在该分支,无需创建tag分支,直接切换") 77 | execCmd("git checkout "+branchtagname) 78 | 79 | #退出子目录 80 | os.chdir(currentDir) 81 | else: 82 | #进入子目录 83 | os.chdir(gitIntoPath) 84 | if branch_name.strip()!='' and branch_name.find("tag:",0,len(branch_name))==-1: 85 | #查看本地分支 86 | isExistBranchAtLocal=isBranchExist(branch_name) 87 | if isExistBranchAtLocal is False: 88 | execCmd("git checkout --track "+" origin/"+branch_name) 89 | else: 90 | execCmd("git checkout "+branch_name) 91 | execCmd("git pull") 92 | elif branch_name.strip()!='' and branch_name.find("tag:",0,len(branch_name))!=-1: 93 | #switch tag 94 | arrayTag = branch_name.split(":") 95 | branchtagname=arrayTag[1]+"-from-tags" 96 | #if branchname exists 97 | isExistBranchAtLocal=isBranchExist(branchtagname) 98 | if isExistBranchAtLocal is False: 99 | execCmd("git checkout "+arrayTag[1]) 100 | execCmd("git checkout -b "+branchtagname) 101 | execCmd("git push origin "+branchtagname) 102 | execCmd("git branch --set-upstream-to=origin/"+branchtagname+" "+branchtagname) 103 | else: 104 | print("##################tag 本地已存在该分支,无需创建tag分支,直接切换") 105 | execCmd("git checkout "+branchtagname) 106 | #退出子目录 107 | os.chdir(currentDir) 108 | f.close() 109 | -------------------------------------------------------------------------------- /AppSwitcherConfig.txt: -------------------------------------------------------------------------------- 1 | https://github.com/HomHomLin/Dilutions;Dilutions;master -------------------------------------------------------------------------------- /Dilutions/android.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.jfrog.bintray' 2 | apply plugin: 'maven-publish' 3 | 4 | group = GROUP_ID 5 | version = DEPLOY_VERSION 6 | project.archivesBaseName = POM_ARTIFACT_ID 7 | 8 | task sourcesJar(type: Jar) { 9 | from android.sourceSets.main.java.srcDirs 10 | classifier = 'sources' 11 | } 12 | task javadoc(type: Javadoc) { 13 | source = android.sourceSets.main.java.srcDirs 14 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 15 | } 16 | task javadocJar(type: Jar, dependsOn: javadoc) { 17 | classifier = 'javadoc' 18 | from javadoc.destinationDir 19 | } 20 | artifacts { 21 | archives javadocJar 22 | archives sourcesJar 23 | } 24 | 25 | def pomConfig = { 26 | licenses { 27 | license { 28 | name "The Apache Software License, Version 2.0" 29 | url "http://www.apache.org/licenses/LICENSE-2.0.txt" 30 | distribution "repo" 31 | } 32 | } 33 | developers { 34 | developer { 35 | id DEVELOPER_ID 36 | name DEVELOPER_NAME 37 | email DEVELOPER_EMAIL 38 | } 39 | } 40 | 41 | scm { 42 | url PROJ_WEBSITEURL 43 | } 44 | } 45 | 46 | javadoc { 47 | options{ 48 | encoding "UTF-8" 49 | charSet 'UTF-8' 50 | author true 51 | version true 52 | links "http://docs.oracle.com/javase/7/docs/api" 53 | title POM_ARTIFACT_ID 54 | } 55 | } 56 | 57 | afterEvaluate { 58 | publishing.publications.mavenJava.artifact(bundleRelease) 59 | } 60 | 61 | publishing { 62 | publications { 63 | mavenJava(MavenPublication) { 64 | artifact javadocJar 65 | artifact sourcesJar 66 | groupId GROUP_ID 67 | artifactId POM_ARTIFACT_ID 68 | version DEPLOY_VERSION 69 | pom{ 70 | packaging 'aar' 71 | } 72 | pom.withXml { 73 | def root = asNode() 74 | root.children().last() + pomConfig 75 | } 76 | } 77 | } 78 | } 79 | 80 | Properties properties = new Properties() 81 | InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream() ; 82 | properties.load( inputStream ) 83 | 84 | def BINTRAY_U = properties.getProperty( 'BINTRAY_USER' ) 85 | def BINTRAY_KEY = properties.getProperty( 'BINTRAY_KEY' ) ; 86 | 87 | bintray { 88 | 89 | user = BINTRAY_U 90 | key = BINTRAY_KEY 91 | 92 | configurations = ['archives'] 93 | publications = ['mavenJava'] 94 | 95 | dryRun = false 96 | publish = true 97 | 98 | pkg { 99 | repo = 'maven' 100 | name = POM_ARTIFACT_ID 101 | licenses = ['Apache-2.0'] 102 | vcsUrl = PROJ_VCSURL 103 | websiteUrl = PROJ_WEBSITEURL 104 | issueTrackerUrl = PROJ_ISSUETRACKERURL 105 | publicDownloadNumbers = true 106 | version { 107 | name = DEPLOY_VERSION 108 | desc = PROJ_DESCRIPTION 109 | vcsTag = DEPLOY_VERSION 110 | 111 | gpg { 112 | sign = true 113 | } 114 | } 115 | } 116 | } 117 | 118 | -------------------------------------------------------------------------------- /Dilutions/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | 4 | android { 5 | // android.enforceUniquePackageName = false 6 | compileSdkVersion 24 7 | buildToolsVersion '26.0.2' 8 | 9 | defaultConfig { 10 | minSdkVersion 14 11 | targetSdkVersion 24 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | lintOptions{ 24 | abortOnError false 25 | } 26 | } 27 | 28 | dependencies { 29 | compile fileTree(dir: 'libs', include: ['*.jar']) 30 | provided 'com.android.support:appcompat-v7:24.2.1' 31 | compile 'com.alibaba:fastjson:1.1.55.android' 32 | } 33 | 34 | apply from: 'android.gradle' 35 | //apply plugin: 'com.novoda.bintray-release' 36 | // 37 | //publish { 38 | // artifactId = POM_LIB_ARTIFACT_ID 39 | // userOrg = DEVELOPER_ID 40 | // groupId = GROUP_ID 41 | // uploadName = POM_ARTIFACT_ID 42 | // publishVersion = DEPLOY_VERSION 43 | // desc = PROJ_DESCRIPTION 44 | // website = PROJ_WEBSITEURL 45 | // licences = ['Apache-2.0'] 46 | //} -------------------------------------------------------------------------------- /Dilutions/gradle.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/Dilutions/f6120cf8334d7cf22c49f6a0fbcc67a75c2b4911/Dilutions/gradle.properties -------------------------------------------------------------------------------- /Dilutions/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/Linhh/Develop/Android/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /Dilutions/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/ActivityDilutionsManager.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.v4.app.Fragment; 7 | 8 | import com.linhonghong.dilutions.annotations.ActivityExtra; 9 | import com.linhonghong.dilutions.annotations.ActivityProtocolExtra; 10 | import com.linhonghong.dilutions.annotations.ActivityProtocolPath; 11 | import com.linhonghong.dilutions.annotations.FragmentArg; 12 | import com.linhonghong.dilutions.annotations.ProtocolFrom; 13 | 14 | import java.lang.annotation.Annotation; 15 | import java.lang.reflect.Field; 16 | import java.util.ArrayList; 17 | 18 | /** 19 | * activity的稀释器管理器 20 | * Created by Linhh on 16/9/2. 21 | */ 22 | public class ActivityDilutionsManager { 23 | 24 | public final ArrayList fieldHandlers; 25 | 26 | ActivityDilutionsManager(Builder builder) { 27 | this.fieldHandlers = builder.fieldHandlers; 28 | } 29 | 30 | public void apply(Activity activity) throws Exception{ 31 | Intent intent = activity.getIntent(); 32 | if(intent == null){ 33 | throw new Exception("intent is null"); 34 | } 35 | Bundle bundle = intent.getExtras(); 36 | if(bundle == null){ 37 | throw new Exception("bundle is null"); 38 | } 39 | for(FieldHandler fieldHandler : fieldHandlers){ 40 | fieldHandler.apply(activity, bundle); 41 | } 42 | } 43 | 44 | public void apply(Fragment fragment) throws Exception{ 45 | 46 | Bundle bundle = fragment.getArguments(); 47 | if(bundle == null){ 48 | throw new Exception("bundle is null"); 49 | } 50 | for(FieldHandler fieldHandler : fieldHandlers){ 51 | fieldHandler.apply(fragment, bundle); 52 | } 53 | } 54 | 55 | static final class Builder { 56 | 57 | //该类的所有具有变量 58 | private final ArrayList fieldHandlers = new ArrayList<>(); 59 | 60 | private final Class clazz; 61 | 62 | public Builder(Class clazz) { 63 | this.clazz = clazz; 64 | } 65 | 66 | private void parseFields(){ 67 | Field[] localfield = clazz.getDeclaredFields(); 68 | for(Field field : localfield){ 69 | //得到变量的注解 70 | Annotation[] annotations = field.getDeclaredAnnotations(); 71 | //解析注解 72 | parseAnnotations(field, annotations); 73 | } 74 | } 75 | 76 | private void parseAnnotations(Field field , Annotation[] annotations){ 77 | for(Annotation annotation: annotations){ 78 | FieldHandler fieldHandler = parseAnnotation(field, annotation); 79 | if(fieldHandler == null){ 80 | continue; 81 | } 82 | 83 | //解析成功 84 | fieldHandlers.add(fieldHandler); 85 | } 86 | } 87 | 88 | private FieldHandler parseAnnotation(Field field , Annotation annotation ){ 89 | 90 | if(annotation instanceof ActivityExtra){ 91 | //如果是Activity的注解 92 | ActivityExtra extra = (ActivityExtra)annotation; 93 | return new FieldHandler.ExtraHandler(field, extra.value()); 94 | }else if(annotation instanceof FragmentArg){ 95 | //如果是Fragment的注解 96 | FragmentArg fragmentArg = (FragmentArg)annotation; 97 | return new FieldHandler.FragmentargHandler(field, fragmentArg.value()); 98 | }else if(annotation instanceof ActivityProtocolExtra){ 99 | //协议注解 100 | ActivityProtocolExtra activityProtocolExtra = (ActivityProtocolExtra)annotation; 101 | return new FieldHandler.ActivityProtocolExtraHandler(field, activityProtocolExtra.value()); 102 | }else if(annotation instanceof ActivityProtocolPath){ 103 | //协议 104 | ActivityProtocolPath activityProtocolPath = (ActivityProtocolPath)annotation; 105 | return new FieldHandler.ActivityProtocolPathHandler(field, activityProtocolPath.value()); 106 | 107 | }else if(annotation instanceof ProtocolFrom){ 108 | //协议 109 | ProtocolFrom protocolFrom = (ProtocolFrom)annotation; 110 | return new FieldHandler.ActivityProtocolFromHandler<>(field, protocolFrom.value()); 111 | 112 | } 113 | 114 | return null; 115 | } 116 | 117 | public ActivityDilutionsManager build() { 118 | parseFields(); 119 | return fieldHandlers.size() > 0 ? new ActivityDilutionsManager(this) : null; 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/Dilutions.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | import android.content.Context; 4 | import android.net.Uri; 5 | 6 | import com.alibaba.fastjson.JSON; 7 | import com.alibaba.fastjson.JSONObject; 8 | import com.linhonghong.dilutions.data.DilutionsConfig; 9 | import com.linhonghong.dilutions.data.DilutionsConfigFactory; 10 | import com.linhonghong.dilutions.data.DilutionsGlobalListener; 11 | import com.linhonghong.dilutions.utils.Checker; 12 | import com.linhonghong.dilutions.utils.DilutionsUtil; 13 | import com.linhonghong.dilutions.interfaces.DilutionsCallBack; 14 | import com.linhonghong.dilutions.interfaces.DilutionsInterceptor; 15 | import com.linhonghong.dilutions.interfaces.DilutionsPathInterceptor; 16 | import com.linhonghong.dilutions.utils.DilutionsUriBuilder; 17 | 18 | import java.lang.reflect.InvocationHandler; 19 | import java.lang.reflect.Method; 20 | import java.lang.reflect.Proxy; 21 | import java.util.ArrayList; 22 | import java.util.HashMap; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | /** 27 | * 稀释项目框架 28 | * 提供模块间以及UI间的高性能解耦数据通信功能 29 | * 请不要随意修改该框架,谢谢合作 30 | * 如果有需要修改请先联系林宏弘,谢谢 31 | * Created by Linhh on 16/9/2. 32 | */ 33 | public class Dilutions { 34 | 35 | private final DilutionsInstrument dilutionsInstrument; 36 | // private static boolean mIsInit = false; 37 | 38 | private static Dilutions dilutions; 39 | 40 | /** 41 | * 初始化,需要在application内初始化 42 | * @param context 43 | */ 44 | @Deprecated 45 | public static void init(Context context, String pathname){ 46 | if(dilutions == null){ 47 | List path_list = new ArrayList<>(); 48 | if(!DilutionsUtil.isNull(pathname)) { 49 | path_list.add(pathname); 50 | } 51 | 52 | dilutions = new Dilutions.Builder() 53 | .pathName(path_list) 54 | .context(context) 55 | .build(); 56 | } 57 | } 58 | 59 | public static void init(Context context, List pathname){ 60 | if(dilutions == null){ 61 | dilutions = new Dilutions.Builder() 62 | .pathName(pathname) 63 | .context(context) 64 | .build(); 65 | } 66 | } 67 | 68 | public static void init(Context context){ 69 | init(context, DilutionsInstrument.PATH_JUMP_FILE); 70 | } 71 | 72 | public static Dilutions create(){ 73 | if(dilutions == null){ 74 | //没有初始化成功,错误 75 | return null; 76 | } 77 | return dilutions; 78 | } 79 | 80 | Dilutions(Builder builder) { 81 | dilutionsInstrument = new DilutionsInstrument(builder.context, builder.pathName); 82 | try { 83 | //初始化 84 | dilutionsInstrument.init(); 85 | } catch (Exception e) { 86 | e.printStackTrace(); 87 | } 88 | } 89 | 90 | public void removeDilutionsPathInterceptor(String path, DilutionsPathInterceptor interceptor){ 91 | dilutionsInstrument.removeDilutionsPathInterceptor(path, interceptor); 92 | } 93 | 94 | public void setDilutionsPathInterceptor(String path ,DilutionsPathInterceptor dilutionsPathInterceptor) { 95 | dilutionsInstrument.setDilutionsPathInterceptor(path, dilutionsPathInterceptor); 96 | } 97 | 98 | @Deprecated 99 | public void setDilutionsGlobalListener(DilutionsGlobalListener dilutionsGlobalListener){ 100 | dilutionsInstrument.setDilutionsGlobalListener(dilutionsGlobalListener); 101 | } 102 | 103 | /** 104 | * 处理HTtp协议 105 | * @param uri_string 106 | */ 107 | public boolean formatProtocolService(final String uri_string){ 108 | return formatProtocolService(uri_string, null); 109 | } 110 | 111 | /** 112 | * 自定义协议发起 113 | * @param scheme 114 | * @param path 115 | * @param query_json 116 | * @return 117 | */ 118 | public boolean formatProtocolService(final String scheme, final String path, final String query_json){ 119 | return formatProtocolService(DilutionsUriBuilder.buildUri(scheme, path, query_json)); 120 | } 121 | 122 | public boolean formatProtocolService(final String scheme, final String path, final JSONObject query_json){ 123 | return formatProtocolService(DilutionsUriBuilder.buildUri(scheme, path, query_json)); 124 | } 125 | 126 | public boolean formatProtocolService(final String scheme, final String path, final org.json.JSONObject query_json){ 127 | return formatProtocolService(scheme, path, query_json.toString()); 128 | } 129 | 130 | // public boolean formatProtocolService(final String scheme, final String path, final Bundle query_json){ 131 | // return formatProtocolService(scheme, path, JSON.toJSONString(query_json)); 132 | // } 133 | 134 | public boolean formatProtocolService(final String scheme, final String path, final Map map){ 135 | String json = JSON.toJSONString(map); 136 | return formatProtocolService(DilutionsUriBuilder.buildUri(scheme, path, json)); 137 | } 138 | 139 | /** 140 | * 带有监听的协议解析 141 | * @param uri_string 142 | * @param config 143 | */ 144 | public boolean formatProtocolService(final String uri_string, final DilutionsConfig config){ 145 | return formatProtocolService(uri_string, null, config); 146 | } 147 | 148 | public boolean formatProtocolServiceWithCallback(final String uri_string, final DilutionsCallBack callBack){ 149 | return formatProtocolService(uri_string, null, DilutionsConfigFactory.newBuilder(callBack, null, null).build()); 150 | } 151 | 152 | public boolean formatProtocolServiceWithInterceptor(final String uri_string, final DilutionsInterceptor interceptor){ 153 | return formatProtocolService(uri_string, null, DilutionsConfigFactory.newBuilder(null, interceptor, null).build()); 154 | } 155 | 156 | public Map> getJumpPathMap(){ 157 | return dilutionsInstrument.getJumpPathMap(); 158 | } 159 | 160 | public HashMap> getMethodPathMap(){ 161 | return dilutionsInstrument.getMethodPathMap(); 162 | } 163 | 164 | public boolean checkUri(String s_uri){ 165 | return dilutionsInstrument.checkUri(s_uri); 166 | } 167 | 168 | /** 169 | * 获得appmap 170 | * @return 171 | */ 172 | public List getAppMap(){ 173 | return dilutionsInstrument.getAppMap(); 174 | } 175 | 176 | /** 177 | * 获得appoutmap 178 | * @return 179 | */ 180 | // public List getAppOutMap(){ 181 | // return dilutionsInstrument.getAppOutMap(); 182 | // } 183 | 184 | /** 185 | * 类型检查map 186 | * @return 187 | */ 188 | public Map> getCheckMap(){ 189 | return dilutionsInstrument.getCheckMap(); 190 | } 191 | 192 | public void addScheme(String scheme){ 193 | getAppMap().add(scheme); 194 | } 195 | 196 | /** 197 | * 处理Http协议 198 | * @param uri 199 | */ 200 | public boolean formatProtocolService(final Uri uri){ 201 | return formatProtocolService(uri, null); 202 | } 203 | 204 | public boolean formatProtocolService(final Uri uri, final DilutionsConfig config){ 205 | return formatProtocolService(uri.toString(), null, config); 206 | } 207 | 208 | public boolean formatProtocolServiceWithExtra(final String uri, final HashMap map){ 209 | return formatProtocolService(uri, map, null); 210 | } 211 | 212 | public boolean formatProtocolServiceWithMap(final String uri, final HashMap map, final Map objectMap){ 213 | return formatProtocolService(uri, map, objectMap, null); 214 | } 215 | 216 | public boolean formatProtocolService(final String uri, final HashMap map, final Map objectMap, final DilutionsConfig config){ 217 | try { 218 | DilutionsManager httpProtocolManager = dilutionsInstrument.createHttpManager(Uri.parse(uri), map); 219 | dilutionsInstrument.dilutions(httpProtocolManager,config, objectMap); 220 | return true; 221 | } catch (Exception e) { 222 | e.printStackTrace(); 223 | } 224 | if(dilutionsInstrument.getDilutionsGlobalListener() != null){ 225 | dilutionsInstrument.getDilutionsGlobalListener().onUnSupportUri(uri); 226 | } 227 | return false; 228 | } 229 | 230 | 231 | /** 232 | * 带有监听的http协议处理 233 | * @param uri 234 | * @param config 235 | */ 236 | public boolean formatProtocolService(final String uri, final HashMap map, final DilutionsConfig config){ 237 | return formatProtocolService(uri, map, null, config); 238 | } 239 | 240 | /** 241 | * 不带协议的解析 242 | * @param protocol 243 | * @param 244 | * @return 245 | */ 246 | @SuppressWarnings("unchecked") 247 | public T formatProtocolService(final Class protocol){ 248 | return formatProtocolService(protocol, null); 249 | } 250 | 251 | /** 252 | * 带有回调的协议解析 253 | * @param protocol 254 | * @param config 255 | * @param 256 | * @return 257 | */ 258 | @SuppressWarnings("unchecked") 259 | public T formatProtocolService(final Class protocol, final DilutionsConfig config) { 260 | //只能代理接口 261 | Checker.validateManagerInterface(protocol); 262 | return (T) Proxy.newProxyInstance(protocol.getClassLoader(), new Class[] { protocol }, 263 | new InvocationHandler() { 264 | 265 | @Override public Object invoke(Object proxy, Method method, Object... args) 266 | throws Throwable { 267 | 268 | if (method.getDeclaringClass() == Object.class) { 269 | return method.invoke(this, args); 270 | } 271 | 272 | //获取代理方法 273 | ProtocolManager managerMethod = dilutionsInstrument.createProtocolManager(method , args); 274 | dilutionsInstrument.dilutions(managerMethod, config, null); 275 | // return Void.class; 276 | return Void.class; 277 | } 278 | }); 279 | } 280 | 281 | /** 282 | * 注册Activity 283 | */ 284 | public void register(Object object){ 285 | dilutionsInstrument.register(object); 286 | } 287 | 288 | /** 289 | * Activity的newIntent,暂时使用register 290 | * @param object 291 | */ 292 | public void onNewIntent(Object object){ 293 | dilutionsInstrument.register(object); 294 | } 295 | 296 | /** 297 | * 构造器 298 | */ 299 | private static final class Builder { 300 | 301 | Context context; 302 | List pathName; 303 | 304 | public Builder() { 305 | 306 | } 307 | 308 | public Builder context(Context context){ 309 | this.context = context; 310 | return this; 311 | } 312 | 313 | public Builder pathName(List pathName){ 314 | this.pathName = pathName; 315 | return this; 316 | } 317 | 318 | public Dilutions build() { 319 | return new Dilutions(this); 320 | } 321 | } 322 | } 323 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/DilutionsBuilder.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | 7 | import com.alibaba.fastjson.JSONObject; 8 | import com.linhonghong.dilutions.data.DilutionsData; 9 | 10 | import java.io.Serializable; 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | /** 15 | * Created by Linhh on 16/11/30. 16 | */ 17 | 18 | public class DilutionsBuilder { 19 | Intent extrasIntent = new Intent(); 20 | Map extras = new HashMap<>(); 21 | JSONObject jsonObject = new JSONObject(); 22 | JSONObject paramsJson = new JSONObject(); 23 | Uri uri; 24 | 25 | private DilutionsData data; 26 | 27 | private int mProtocolFrom;//来自哪里的跳转? 28 | 29 | private String mPath; 30 | private Context mContext; 31 | private ProtocolClazzORMethod protocolClazzORMethod; 32 | 33 | private Object what; 34 | 35 | DilutionsBuilder(Context context){ 36 | mContext = context; 37 | } 38 | 39 | class Extra{ 40 | public Object value; 41 | public Class type; 42 | } 43 | 44 | public String getPath(){ 45 | return mPath; 46 | } 47 | 48 | public void setFrom(int from){ 49 | mProtocolFrom = from; 50 | } 51 | 52 | public void setUri(Uri uri){ 53 | this.uri = uri; 54 | } 55 | 56 | public int getFrom(){ 57 | return mProtocolFrom; 58 | } 59 | /** 60 | * 添加post参数 61 | * @param name 62 | * @param value 63 | */ 64 | public void addParams(String name, Object value, Class type) throws Exception{ 65 | Extra extra = new Extra(); 66 | extra.type = type; 67 | extra.value = value; 68 | jsonObject.put(name, value); 69 | extras.put(name, extra); 70 | // extras.put(name,value); 71 | } 72 | 73 | public void setClazz(int protocolType, Context context, String path, ProtocolClazzORMethod clazz){ 74 | if(protocolType == DilutionsValue.PROTOCOL_JUMP){ 75 | extrasIntent.setClass(mContext, clazz.clazz); 76 | extrasIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 77 | } 78 | protocolClazzORMethod = clazz; 79 | mPath = path; 80 | } 81 | 82 | public void setClazz(int protocolType, String path, ProtocolClazzORMethod clazz){ 83 | setClazz(protocolType, mContext, path, clazz); 84 | } 85 | 86 | public void setWhat(Object what){ 87 | this.what = what; 88 | } 89 | 90 | public DilutionsData getDilutionsData(){ 91 | if(data == null){ 92 | data = new DilutionsData(); 93 | } 94 | data.setIntent(getIntent()); 95 | data.setWhat(what); 96 | data.setUri(uri); 97 | data.setList(protocolClazzORMethod.mParamsList); 98 | return data; 99 | } 100 | 101 | public Intent getIntent(){ 102 | // intent.putExtra(URI_CALL_PATH, path); 103 | paramsJson.put(DilutionsValue.VAL_PARAMS, jsonObject); 104 | putExtra(extrasIntent); 105 | extrasIntent.putExtra(DilutionsInstrument.URI_CALL_CLASS, protocolClazzORMethod.clazz); 106 | extrasIntent.putExtra(DilutionsInstrument.URI_CALL_PATH, mPath); 107 | extrasIntent.putExtra(DilutionsInstrument.URI_CALL_PARAM,paramsJson.toString()); 108 | extrasIntent.putExtra(DilutionsInstrument.URI_FROM, mProtocolFrom); 109 | //可能来自代理跳转的,不存在uri 110 | extrasIntent.putExtra(DilutionsInstrument.URI_CALL_ALL, uri == null ? "from clazz protocol" : uri.toString()); 111 | return extrasIntent; 112 | } 113 | 114 | public Intent putExtra(Intent intent){ 115 | for (Map.Entry entry : extras.entrySet()) { 116 | String key = entry.getKey(); 117 | Extra extra = entry.getValue(); 118 | Object obj = extra.value; 119 | Class type = extra.type; 120 | // checkMap.put("int", Integer.class); 121 | // checkMap.put("String", String.class); 122 | // checkMap.put("long", Long.class); 123 | // checkMap.put("double", Double.class); 124 | // checkMap.put("boolean", Boolean.class); 125 | // checkMap.put("float",Float.class); 126 | if(type == String.class){ 127 | String value = (String)obj; 128 | intent.putExtra(key, value); 129 | }else if(type == Integer.class || type == int.class){ 130 | Integer value = (Integer)obj; 131 | intent.putExtra(key,value); 132 | }else if(type == Long.class || type == long.class){ 133 | Long value = (Long)obj; 134 | intent.putExtra(key,value); 135 | }else if(type == Double.class || type == double.class){ 136 | Double value = (Double)obj; 137 | intent.putExtra(key,value); 138 | }else if(type == Boolean.class || type == boolean.class){ 139 | Boolean value = (Boolean)obj; 140 | intent.putExtra(key,value); 141 | }else if(type == Float.class || type == float.class){ 142 | Float value = (Float)obj; 143 | intent.putExtra(key,value); 144 | } 145 | else{ 146 | try { 147 | intent.putExtra(key, (Serializable) obj); 148 | }catch (Exception e){ 149 | //不支持该类型 150 | e.printStackTrace(); 151 | } 152 | } 153 | } 154 | return intent; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/DilutionsFunction.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | import com.linhonghong.dilutions.data.DilutionsData; 4 | 5 | /** 6 | * Created by Linhh on 16/12/16. 7 | */ 8 | 9 | public interface DilutionsFunction { 10 | public void onDilutions(DilutionsData data); 11 | } 12 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/DilutionsInstrument.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.net.Uri; 7 | import android.os.Bundle; 8 | import android.support.v4.app.ActivityCompat; 9 | import android.support.v4.app.ActivityOptionsCompat; 10 | import android.support.v4.app.Fragment; 11 | 12 | import com.alibaba.fastjson.JSON; 13 | import com.alibaba.fastjson.JSONObject; 14 | import com.linhonghong.dilutions.data.DilutionsConfig; 15 | import com.linhonghong.dilutions.data.DilutionsData; 16 | import com.linhonghong.dilutions.data.DilutionsGlobalListener; 17 | import com.linhonghong.dilutions.utils.DilutionsUtil; 18 | import com.linhonghong.dilutions.interfaces.DilutionsCallBack; 19 | import com.linhonghong.dilutions.interfaces.DilutionsInterceptor; 20 | import com.linhonghong.dilutions.interfaces.DilutionsPathInterceptor; 21 | 22 | import java.io.InputStream; 23 | import java.lang.reflect.Method; 24 | import java.util.ArrayList; 25 | import java.util.Enumeration; 26 | import java.util.HashMap; 27 | import java.util.LinkedHashMap; 28 | import java.util.List; 29 | import java.util.Map; 30 | import java.util.Properties; 31 | 32 | /** 33 | * Created by Linhh on 16/9/2. 34 | */ 35 | public class DilutionsInstrument { 36 | public static final String TAG = "Dilutions_info"; 37 | 38 | public static final String URI_CALL_CLASS = "uri-call-clazz"; 39 | public static final String URI_CALL_PATH = "uri-call-path"; 40 | public static final String URI_CALL_PARAM = "uri-call-param"; 41 | public static final String URI_CALL_ALL = "uri-call-all"; 42 | public static final String URI_FROM = "uri-from"; 43 | public static final String SCHEME_IN = "DILUTIONS.SCHEME.IN"; 44 | public static final String SCHEME_OUT = "DILUTIONS.SCHEME.OUT"; 45 | // public static final String APP_SCHEME = "dilutions";//公共内部协议 46 | 47 | // public static final String COMPATIBLE_METHOD_NAME = "dilutionsCall"; 48 | 49 | public static final String PATH_JUMP_FILE = "uiInterpreter.conf"; 50 | 51 | private DilutionsGlobalListener mDilutionsGlobalListener; 52 | 53 | public static final int PARSER_TYPE_JUMP = 0; 54 | public static final int PARSER_TYPE_METHOD = 1; 55 | 56 | private final Map, ActivityDilutionsManager> managerCache = new LinkedHashMap<>(); 57 | 58 | //方法缓存 59 | private final Map protocolCache = new LinkedHashMap<>(); 60 | private final Map protocolClazzORMethodMap = new HashMap<>(); 61 | 62 | private Map> jumpPathMap;//pathMap, key = 协议/my/info, value = com.activity 63 | private final Map> jumpParamsMap = new HashMap<>();//paramsMap key = 协议/my/info , value = 参数以及检查类型 64 | 65 | private HashMap> methodPathMap;//pathMap, key = 协议/my/info, value = com.activity 66 | // private final Map> methodParamsMap = new HashMap<>();//paramsMap key = 协议/my/info , value = 参数以及检查类型 67 | 68 | private final Map> checkMap = new HashMap<>();//参数合法性检查 69 | private final List appMap = new ArrayList<>();//协议头map 70 | private final HashMap> mDilutionsPathInterceptor = new HashMap<>(); 71 | // private final List appOutMap = new ArrayList<>();//协议外 72 | 73 | private Context mContext; 74 | private List mPathName; 75 | 76 | DilutionsInstrument(Context context, List pathName){ 77 | mContext = context; 78 | // mPathName = pathName; 79 | } 80 | 81 | void removeDilutionsPathInterceptor(String path, DilutionsPathInterceptor interceptor){ 82 | ArrayList interceptors = mDilutionsPathInterceptor.get(path); 83 | if(interceptors != null) { 84 | interceptors.remove(interceptor); 85 | } 86 | } 87 | 88 | void setDilutionsPathInterceptor(String path ,DilutionsPathInterceptor dilutionsPathInterceptor){ 89 | ArrayList interceptors = mDilutionsPathInterceptor.get(path); 90 | if(interceptors == null){ 91 | interceptors = new ArrayList<>(); 92 | } 93 | if(interceptors.size() == 0){ 94 | interceptors.add(dilutionsPathInterceptor); 95 | mDilutionsPathInterceptor.put(path, interceptors); 96 | return; 97 | } 98 | for(int i = 0; i < interceptors.size(); i ++){ 99 | DilutionsPathInterceptor interceptor = interceptors.get(i); 100 | if(interceptor.level() == dilutionsPathInterceptor.level()){ 101 | // Log.e(TAG, "path:" + path + ",拦截器添加失败、已经存在" + interceptor.getClass() + ",级别:" + dilutionsPathInterceptor.level()); 102 | return; 103 | } 104 | if(interceptor.level() < dilutionsPathInterceptor.level()){ 105 | interceptors.add(i, dilutionsPathInterceptor); 106 | mDilutionsPathInterceptor.put(path, interceptors); 107 | return; 108 | } 109 | } 110 | interceptors.add(dilutionsPathInterceptor); 111 | mDilutionsPathInterceptor.put(path, interceptors); 112 | 113 | } 114 | 115 | void setDilutionsGlobalListener(DilutionsGlobalListener dilutionsGlobalListener){ 116 | if(mDilutionsGlobalListener != null){ 117 | // Log.e(TAG, "DilutionsGlobalListener is already exists."); 118 | return; 119 | } 120 | mDilutionsGlobalListener = dilutionsGlobalListener; 121 | } 122 | 123 | DilutionsGlobalListener getDilutionsGlobalListener(){ 124 | return mDilutionsGlobalListener; 125 | } 126 | 127 | /** 128 | * 初始化 129 | */ 130 | public void init() throws Exception{ 131 | initUIProtocol(); 132 | initMethodProtocol(); 133 | if(jumpPathMap == null){ 134 | jumpPathMap = new HashMap<>(); 135 | } 136 | if(methodPathMap == null){ 137 | methodPathMap = new HashMap<>(); 138 | } 139 | initCheckMap(); 140 | initAppMap(); 141 | //解析path 142 | // if(mPathName != null) { 143 | // for (String pathname : mPathName) { 144 | // parserData(pathname, PARSER_TYPE_JUMP); 145 | // } 146 | // } 147 | } 148 | 149 | public Map> getJumpPathMap(){ 150 | return jumpPathMap; 151 | } 152 | 153 | public HashMap> getMethodPathMap(){ 154 | return methodPathMap; 155 | } 156 | 157 | /** 158 | * 初始化数据类型处理器 159 | */ 160 | private void initCheckMap(){ 161 | checkMap.put("int", Integer.class); 162 | checkMap.put("String", String.class); 163 | checkMap.put("long", Long.class); 164 | checkMap.put("double", Double.class); 165 | checkMap.put("boolean", Boolean.class); 166 | checkMap.put("float",Float.class); 167 | // checkMap.put("Serializable", Serializable.class); 168 | // int a = int.class.cast(checkMap); 169 | } 170 | 171 | /** 172 | * 初始化方法协议 173 | */ 174 | private void initMethodProtocol(){ 175 | try { 176 | Class methodMapClazz = Class.forName("com.linhonghong.dilutions.inject.support.DilutionsInjectMetas"); 177 | Object obj = methodMapClazz.newInstance(); 178 | 179 | Method method = methodMapClazz.getMethod("getMap"); 180 | methodPathMap = (HashMap>) method.invoke(obj); 181 | }catch (Exception e){ 182 | e.printStackTrace(); 183 | } 184 | } 185 | 186 | /** 187 | * 初始化UI协议 188 | */ 189 | private void initUIProtocol() throws Exception{ 190 | try { 191 | Class methodMapClazz = Class.forName("com.linhonghong.dilutions.inject.support.DilutionsInjectUIMetas"); 192 | Object obj = methodMapClazz.newInstance(); 193 | 194 | Method method = methodMapClazz.getMethod("getMap"); 195 | jumpPathMap = (HashMap>) method.invoke(obj); 196 | }catch (Exception e){ 197 | e.printStackTrace(); 198 | } 199 | } 200 | 201 | public Map> getCheckMap(){ 202 | return checkMap; 203 | } 204 | 205 | public HttpProtocolManager createHttpManager(Uri uri, HashMap map) throws Exception{ 206 | return new HttpProtocolManager.Builder(this, uri, map).build(); 207 | } 208 | 209 | /** 210 | * 初始化appmap 211 | */ 212 | private void initAppMap(){ 213 | //默认 214 | appMap.add("dilutions"); 215 | } 216 | 217 | /** 218 | * 获得appmap 219 | * @return 220 | */ 221 | public List getAppMap(){ 222 | return appMap; 223 | } 224 | 225 | /** 226 | * 获得appoutmap 227 | * @return 228 | */ 229 | // public List getAppOutMap(){ 230 | // return appOutMap; 231 | // } 232 | 233 | // Map> getParamsMap(int type) throws Exception{ 234 | // switch (type){ 235 | // case DilutionsValue.PROTOCOL_JUMP: 236 | // return jumpParamsMap; 237 | // case DilutionsValue.PROTOCOL_METHOD: 238 | // return methodParamsMap; 239 | // default: 240 | // throw new Exception("no params"); 241 | // } 242 | // } 243 | 244 | /** 245 | * 旧的协议配置解析 246 | * 解析数据 247 | * @param name 248 | * @throws Exception 249 | */ 250 | @Deprecated 251 | private void parserData(String name, int type) throws Exception{ 252 | // InputStream pathis = getContext().getAssets().open(name); 253 | // Properties properties = new Properties(); 254 | // properties.load(pathis); 255 | // Enumeration keys = properties.keys(); 256 | // while (keys.hasMoreElements()) { 257 | // String key = (String) keys.nextElement();//协议 258 | // String value = properties.getProperty(key).trim(); 259 | // if(DilutionsUtil.isEqual(SCHEME_IN, key)){ 260 | // //配置头 261 | // parseScheme(appMap, value); 262 | // }else if(DilutionsUtil.isEqual(SCHEME_OUT, key)){ 263 | // //配置头 264 | //// parseScheme(appOutMap, value); 265 | // }else { 266 | // parseQuery(key, value, jumpPathMap); 267 | //// switch (type) { 268 | //// case PARSER_TYPE_JUMP: 269 | //// //解析跳转 270 | //// parseQuery(key, value, jumpPathMap); 271 | //// break; 272 | //// case PARSER_TYPE_METHOD: 273 | //// //解析方法 274 | //// if (value.contains("#")) { 275 | //// //解析方法协议 276 | //// parseQuery(key, value, methodPathMap); 277 | //// } else { 278 | //// //兼容模式 279 | //// value = value.contains(COMPATIBLE_METHOD_PACKAGE) ? value : COMPATIBLE_METHOD_PACKAGE + value; 280 | //// value = value + "#" + COMPATIBLE_METHOD_NAME; 281 | //// parseQuery(key, value, methodPathMap); 282 | //// } 283 | //// break; 284 | //// } 285 | // } 286 | // } 287 | } 288 | 289 | /** 290 | * 解析参数 291 | * @param key 292 | * @param value 293 | * @return true 解析成功,false失败 294 | */ 295 | private boolean parseQuery(String key, String value, Map> pathMap){ 296 | String[] sp = value.split("\\(");//窃取数据 297 | // if (sp.length < 2) { 298 | // //只有一条数据,解析错误 299 | //// throw new Exception("配置文件出错,位置:" + key + ",找不到参数"); 300 | // Log.e(TAG,"Config error, config position: " + key + " ,dilutions couldn't solve this config key."); 301 | // return false; 302 | // } 303 | String path = sp[0].trim(); 304 | ArrayList list = new ArrayList<>(); 305 | list.add(path); 306 | // if(type == PARSER_TYPE_JUMP) { 307 | pathMap.put(key, list);//将跳转位置加入path, class类 308 | // }else if(type == PARSER_TYPE_METHOD){ 309 | // //方法处理 310 | // pathMap.put(key, path);//将跳转位置加入path, class类 311 | // } 312 | 313 | // String[] querys = sp[1].split("\\)"); 314 | // 315 | // //该处可以被优化 316 | // Map queryMap = new HashMap<>(); 317 | // 318 | // if(querys.length > 0) { 319 | // //有参数 320 | // String query = querys[0].trim();//参数数据 321 | // 322 | // String[] params = query.split(",");//解析参数数据,可能为空参数 323 | // for (String param : params) { 324 | // String[] data = param.trim().split(" ");//解析参数类型 325 | // if (data.length < 2) { 326 | // //如果数据有问题就直接跳过 327 | // continue; 328 | // } 329 | // //1为数据名,0为类型 330 | // queryMap.put(data[1].trim(), data[0].trim());//将参数数据加入表 331 | // } 332 | // } 333 | // 334 | // paramsMap.put(key, queryMap);//将数据表加入参数数据,参数 335 | 336 | return true; 337 | } 338 | 339 | public void parseScheme(List map , String value){ 340 | String[] params = value.split(","); 341 | for(String param : params){ 342 | String in = param.trim().substring(1, param.length() - 1); 343 | if(!map.contains(in)) { 344 | map.add(in); 345 | } 346 | } 347 | } 348 | 349 | /** 350 | * 检查数据合法性 351 | */ 352 | boolean checkJumpUriSafe(String scheme, String path){ 353 | // return jumpPathMap.containsKey(path); 354 | // if (scheme.contains(APP_SCHEME)) { 355 | // return jumpPathMap.containsKey(path); 356 | // } 357 | for (int i = 0; i < appMap.size(); ++i) { 358 | if (scheme.contains(appMap.get(i))) { 359 | return jumpPathMap.containsKey(path); 360 | } 361 | } 362 | return false; 363 | // return pathMap.containsKey(path); 364 | } 365 | 366 | public int getUriType(String path) throws Exception{ 367 | if(jumpPathMap.containsKey(path)){ 368 | return DilutionsValue.PROTOCOL_JUMP; 369 | }else if(methodPathMap.containsKey(path)){ 370 | return DilutionsValue.PROTOCOL_METHOD; 371 | } 372 | throw new Exception("Uri协议出错,不存在[" + path + "]协议"); 373 | } 374 | 375 | public int getUriType(String scheme, String path) throws Exception{ 376 | if(checkJumpUriSafe(scheme,path)){ 377 | return DilutionsValue.PROTOCOL_JUMP; 378 | }else if(checkMethodUriSafe(scheme, path)){ 379 | return DilutionsValue.PROTOCOL_METHOD; 380 | } 381 | throw new Exception("Uri协议出错,不存在[" + scheme + "][" + path + "]协议"); 382 | } 383 | 384 | /** 385 | * 检查方法数据合法性 386 | */ 387 | boolean checkMethodUriSafe(String scheme, String path){ 388 | // return methodPathMap.containsKey(path); 389 | // if (scheme.contains(APP_SCHEME)) { 390 | // return methodPathMap.containsKey(path); 391 | // } 392 | for (int i = 0; i < appMap.size(); ++i) { 393 | if (scheme.contains(appMap.get(i))) { 394 | return methodPathMap.containsKey(path); 395 | } 396 | } 397 | return false; 398 | // return pathMap.containsKey(path); 399 | } 400 | 401 | /** 402 | * 注册稀释器 403 | */ 404 | public void register(Object object){ 405 | Class clazz = object.getClass(); 406 | if(object instanceof Activity){ 407 | //是Activity 408 | registerActivity(clazz, object); 409 | }else if(object instanceof Fragment){ 410 | //是fragment 411 | registerFragment(clazz, object); 412 | }else{ 413 | //无法识别 414 | return; 415 | } 416 | } 417 | 418 | private ActivityDilutionsManager getManager(Class clazz){ 419 | //得到当前Activity的所有对象 420 | ActivityDilutionsManager result; 421 | //不要使用缓存,因为所在的args是不同的 422 | synchronized (managerCache) { 423 | result = managerCache.get(clazz); 424 | if (result == null) { 425 | result = new ActivityDilutionsManager.Builder(clazz).build(); 426 | managerCache.put(clazz, result); 427 | } 428 | } 429 | 430 | return result; 431 | } 432 | 433 | /** 434 | * 注册Activity 435 | * @param clazz 436 | * @param object 437 | */ 438 | private void registerActivity(Class clazz, Object object){ 439 | //得到当前Activity的所有对象 440 | ActivityDilutionsManager result = getManager(clazz); 441 | try { 442 | if(result != null) { 443 | result.apply((Activity) object); 444 | } 445 | }catch (Exception e){ 446 | e.printStackTrace(); 447 | } 448 | } 449 | 450 | /** 451 | * 设置http协议参数 452 | * @param jsonObject 453 | */ 454 | public void createExtraParams(ArrayList> parameterHandlers, String path, JSONObject jsonObject) throws Exception{ 455 | //2017.7.6修改,3.0特殊处理,如果jsonobJECT为空,不抛出错误 456 | if(jsonObject == null ){ 457 | jsonObject = new JSONObject(); 458 | } 459 | if(DilutionsUtil.isNull(path)){ 460 | //JSON为空,无法解析 461 | throw new Exception("path is null"); 462 | } 463 | //获得参数以及其类型,限制性做法 464 | for(Map.Entry entry : jsonObject.entrySet()){ 465 | String key = entry.getKey(); 466 | // Class clazz = getParamsType(path, key); 467 | // if(clazz == null){ 468 | // //没有配置转换类型 469 | // continue; 470 | // } 471 | Object value = jsonObject.get(key); 472 | if(value != null) { 473 | Class clazz = value.getClass(); 474 | ParameterHanlder.ExtraParams parameterHandler = new ParameterHanlder.ExtraParams<>(key, clazz.cast(value)); 475 | parameterHandler.setType(clazz); 476 | parameterHandlers.add(parameterHandler); 477 | }else{ 478 | //解析空值null 479 | } 480 | } 481 | } 482 | 483 | /** 484 | * 设置http协议参数 485 | * @param jsonObject 486 | */ 487 | public void createExtraParams(Map> paramsMap, ArrayList> parameterHandlers, String path, JSONObject jsonObject){ 488 | if(jsonObject == null || DilutionsUtil.isNull(path)){ 489 | //JSON为空,无法解析 490 | return; 491 | } 492 | Map params = paramsMap.get(path); 493 | if(params == null){ 494 | return; 495 | } 496 | //获得参数以及其类型,限制性做法 497 | for(Map.Entry entry : params.entrySet()){ 498 | String key = entry.getKey(); 499 | Class clazz = getParamsType(path, key); 500 | if(clazz == null){ 501 | //没有配置转换类型 502 | continue; 503 | } 504 | Object value = jsonObject.get(key); 505 | if(value != null) { 506 | ParameterHanlder.ExtraParams parameterHandler = new ParameterHanlder.ExtraParams<>(key, clazz.cast(value)); 507 | parameterHandler.setType(clazz); 508 | parameterHandlers.add(parameterHandler); 509 | }else{ 510 | //解析空值 511 | } 512 | } 513 | } 514 | 515 | /** 516 | * 注册Fragment 517 | * @param clazz 518 | * @param object 519 | */ 520 | private void registerFragment(Class clazz, Object object){ 521 | //得到当前Fragment的所有对象 522 | ActivityDilutionsManager result = getManager(clazz); 523 | try { 524 | if(result != null) { 525 | result.apply((Fragment) object); 526 | } 527 | }catch (Exception e){ 528 | e.printStackTrace(); 529 | } 530 | } 531 | 532 | public boolean checkUri(String s_uri){ 533 | boolean result = false; 534 | if(mDilutionsGlobalListener != null){ 535 | result = mDilutionsGlobalListener.onCheckUri(s_uri); 536 | } 537 | if(result){ 538 | return result; 539 | } 540 | try { 541 | Uri uri = Uri.parse(s_uri); 542 | String scheme = uri.getScheme(); 543 | String path = uri.getPath(); 544 | result = checkJumpUriSafe(scheme, path); 545 | if (!result) { 546 | result = checkMethodUriSafe(scheme, path); 547 | } 548 | }catch (Exception e){ 549 | e.printStackTrace(); 550 | } 551 | return result; 552 | } 553 | 554 | 555 | /** 556 | * 创建M层方法管理器 557 | * @param method 558 | * @param args 559 | * @return 560 | */ 561 | ProtocolManager createProtocolManager(Method method, Object... args) { 562 | ProtocolManager result; 563 | //不要使用缓存,因为所在的args是不同的 564 | synchronized (protocolCache) { 565 | result = protocolCache.get(method); 566 | if (result == null) { 567 | result = new ProtocolManager.Builder(this, method).build(); 568 | protocolCache.put(method, result); 569 | } 570 | result.args(args); 571 | } 572 | return result; 573 | } 574 | // 575 | // /** 576 | // * 创建M层方法管理器(网络协议) 577 | // * @param method 578 | // * @param args 579 | // * @return 580 | // */ 581 | // ProtocolManager createProtocolManager(Method method, HashMap args) { 582 | // ProtocolManager result; 583 | // //不要使用缓存,因为所在的args是不同的 584 | // synchronized (protocolCache) { 585 | // result = protocolCache.get(method); 586 | // if (result == null) { 587 | // result = new ProtocolManager.Builder(this, method).build(); 588 | // protocolCache.put(method, result); 589 | // } 590 | // result.args(args); 591 | // } 592 | // return result; 593 | // } 594 | 595 | /** 596 | * 通过path获取需要跳转的class 597 | * @param path 598 | * @return 599 | */ 600 | public ProtocolClazzORMethod getClazz(int protocolType, String path) throws Exception{ 601 | if(protocolClazzORMethodMap.containsKey(path)){ 602 | return protocolClazzORMethodMap.get(path); 603 | } 604 | ProtocolClazzORMethod protocolClazzORMethod = null; 605 | //只会被调用一次 606 | switch (protocolType){ 607 | case DilutionsValue.PROTOCOL_JUMP: 608 | // String enterAnim, exitAnim = null; 609 | ArrayList list = jumpPathMap.get(path); 610 | // enterAnim = list.get(1); 611 | // exitAnim = list.get(2); 612 | Class jumpClazz = Class.forName(list.get(0)); 613 | protocolClazzORMethod = new ProtocolClazzORMethod(jumpClazz, null , path, list, null); 614 | protocolClazzORMethodMap.put(path, protocolClazzORMethod); 615 | return protocolClazzORMethod; 616 | case DilutionsValue.PROTOCOL_METHOD: 617 | //返回方法跳转类和方法名sp[0]=类,sp[1]=方法 618 | Class methodClazz = Class.forName(methodPathMap.get(path).get(0)); 619 | //取出类参数类型 620 | String j = methodPathMap.get(path).get(2); 621 | String[] param_type = null; 622 | if(j == null || j.length() == 0){ 623 | param_type = new String[]{}; 624 | }else { 625 | param_type = j.split("#"); 626 | } 627 | Class[] classes = new Class[param_type.length]; 628 | for(int i = 0 ;i < param_type.length; i++){ 629 | classes[i] = DilutionsUtil.getParamsClass(param_type[i]); 630 | } 631 | protocolClazzORMethod = new ProtocolClazzORMethod(methodClazz, methodPathMap.get(path).get(1), path, methodPathMap.get(path),classes); 632 | protocolClazzORMethodMap.put(path, protocolClazzORMethod); 633 | return protocolClazzORMethod; 634 | default: 635 | throw new Exception("协议错误"); 636 | } 637 | 638 | } 639 | 640 | /** 641 | * 根据配置名获得参数名 642 | * @param param 643 | * @return 644 | */ 645 | // public String getParams(int type, String param, String path){ 646 | // //参数检查,如果参数不在配置中就提示错误 647 | // //只会被调用一次 648 | // switch (type){ 649 | // case DilutionsValue.PROTOCOL_JUMP: 650 | // if(!jumpParamsMap.get(path).containsKey(param)){ 651 | // Log.w(TAG,path + " " + param + " 参数缺失"); 652 | // } 653 | // return param; 654 | // case DilutionsValue.PROTOCOL_METHOD: 655 | // if(!methodParamsMap.get(path).containsKey(param)){ 656 | //// throw new Exception("参数错误"); 657 | // Log.w(TAG,path + " " + param + " 参数缺失"); 658 | // } 659 | // return param; 660 | // default: 661 | // return param; 662 | //// throw new Exception("协议错误"); 663 | // } 664 | // } 665 | 666 | /** 667 | * 获取参数类型 668 | * @param path 669 | * @param param 670 | * @return 671 | */ 672 | public Class getParamsType(String path, String param){ 673 | Map params = jumpParamsMap.get(path); 674 | if(params == null){ 675 | return null; 676 | } 677 | String type = params.get(param); 678 | if(DilutionsUtil.isNull(type)){ 679 | return null; 680 | } 681 | return checkMap.get(type); 682 | } 683 | 684 | /** 685 | * 处理协议 686 | * @param protocolManager 687 | */ 688 | void dilutions(DilutionsManager protocolManager, DilutionsConfig config, Map extraMap) throws Exception{ 689 | protocolManager.apply(); 690 | DilutionsData data = protocolManager.getDilutionsBuilder().getDilutionsData(); 691 | DilutionsCallBack callBack = null; 692 | DilutionsInterceptor interceptor = null; 693 | String path = protocolManager.getDilutionsBuilder().getPath(); 694 | String u = ""; 695 | if(data.getUri() != null){ 696 | u = data.getUri().toString(); 697 | } 698 | // Log.e(TAG, "path:" + path + "协议开始执行。" + u); 699 | if(mDilutionsGlobalListener != null && mDilutionsGlobalListener.onIntercept(data)){ 700 | // Log.e(TAG, "path:" + path + "被拦截,拦截者_全局拦截:" + interceptor.getClass()); 701 | return; 702 | } 703 | //执行协议拦截器 704 | ArrayList interceptors = mDilutionsPathInterceptor.get(path); 705 | if(interceptors != null && interceptors.size() > 0){ 706 | 707 | for(DilutionsPathInterceptor interceptor1 : interceptors){ 708 | if(interceptor1.interceptor(data)){ 709 | // Log.e(TAG, "path:" + path + "被局部拦截,拦截者:" + interceptor1.getClass() + ",level:" + interceptor1.level()); 710 | return; 711 | } 712 | } 713 | } 714 | //处理协议 715 | // Log.d("dilutions", "Process:" + path); 716 | if(config != null){ 717 | callBack = config.getDilutionsCallBack(); 718 | interceptor = config.getDilutionsInterceptor(); 719 | data.setWhat(config.getWhat()); 720 | } 721 | 722 | if(interceptor != null && interceptor.interceptor(data)){ 723 | // Log.e(TAG, "path:" + path + "被拦截,拦截者_发起协议者:" + interceptor.getClass()); 724 | //拦截 725 | return; 726 | } 727 | // try { 728 | //TODO:捕获的原因是因为想让callback继续执行 729 | //处理协议最后逻辑 730 | if (protocolManager.getProtocolType() == DilutionsValue.PROTOCOL_JUMP) { 731 | ArrayList list = data.getList(); 732 | int enterAnim = 0; 733 | int exitAnim = 0; 734 | try{ 735 | String ea = list.get(1); 736 | enterAnim = Integer.valueOf(ea); 737 | }catch (Exception e){ 738 | e.printStackTrace(); 739 | } 740 | 741 | try{ 742 | String ea = list.get(2); 743 | exitAnim = Integer.valueOf(ea); 744 | }catch (Exception e){ 745 | e.printStackTrace(); 746 | } 747 | if(enterAnim != 0 || exitAnim != 0){ 748 | //如果有一个拥有动画,则 749 | ActivityOptionsCompat transitionActivityOptions = 750 | ActivityOptionsCompat.makeCustomAnimation(mContext,enterAnim, exitAnim); 751 | ActivityCompat.startActivities(mContext, 752 | new Intent[]{data.getIntent()}, transitionActivityOptions.toBundle()); 753 | }else { 754 | mContext.startActivity(data.getIntent()); 755 | } 756 | } else if (protocolManager.getProtocolType() == DilutionsValue.PROTOCOL_METHOD) { 757 | //方法解析 758 | // if(!methodMap.containsKey(path)) { 759 | //缓存处理 760 | Class clazz = protocolManager.getProtocolClazzORMethod().clazz; 761 | String methodName = protocolManager.getProtocolClazzORMethod().methodName; 762 | 763 | Object obj = protocolManager.getProtocolClazzORMethod().clazz.newInstance(); 764 | 765 | //取出类参数类型 766 | String j = protocolManager.getProtocolClazzORMethod().mParamsList.get(2); 767 | // String[] param_type = j.split("#"); 768 | // Class[] classes = new Class[param_type.length]; 769 | // for(int i = 0 ;i < param_type.length; i++){ 770 | // classes[i] = DilutionsUtil.getParamsClass(param_type[i]); 771 | // } 772 | 773 | Method method = clazz.getDeclaredMethod(methodName, protocolManager.getProtocolClazzORMethod().mClasses); 774 | if(j.equals("")){ 775 | //空参数 776 | method.invoke(obj); 777 | }else{ 778 | //需要缓存 779 | HashMap indexs = new HashMap<>(); 780 | for(int i = 3; i < protocolManager.getProtocolClazzORMethod().mParamsList.size(); i ++){ 781 | String[] s = protocolManager.getProtocolClazzORMethod().mParamsList.get(i).split("="); 782 | indexs.put(Integer.valueOf(s[0]),s[1]); 783 | } 784 | String[] params_type = j.split("#"); 785 | Object[] objs = new Object[params_type.length]; 786 | Bundle bundle = data.getIntent().getExtras(); 787 | for(int i = 0 ;i < params_type.length; i++){ 788 | 789 | //该位置存在协议名,所以这个地方要解析 790 | //example: 0=tree,i = 0, indexs.get(i) = tree 791 | if (indexs.containsKey(i)) { 792 | //存在字段 793 | Class type = protocolManager.getProtocolClazzORMethod().mClasses[i]; 794 | Object object = bundle.get(indexs.get(i)); 795 | if(object == null){ 796 | //没有该参数,判断是否需要从外部传递的取参 797 | if(extraMap != null){ 798 | object = extraMap.get(indexs.get(i)); 799 | } 800 | if(object == null) { 801 | object = DilutionsUtil.getParams(params_type[i]); 802 | } 803 | }else { 804 | if (type == String.class) { 805 | object = String.valueOf(object); 806 | } else if (type == Integer.class) { 807 | object = Integer.valueOf(String.valueOf(object)); 808 | } else if (type == int.class) { 809 | object = Integer.valueOf(String.valueOf(object)).intValue(); 810 | } else if (type == Long.class) { 811 | object = Long.valueOf(String.valueOf(object)); 812 | } else if (type == long.class) { 813 | object = Long.valueOf(String.valueOf(object)).longValue(); 814 | } else if (type == Double.class) { 815 | object = Double.valueOf(String.valueOf(object)); 816 | } else if (type == double.class) { 817 | object = Double.valueOf(String.valueOf(object)).doubleValue(); 818 | } else if (type == Boolean.class) { 819 | object = Boolean.valueOf(String.valueOf(object)); 820 | } else if (type == boolean.class) { 821 | object = Boolean.valueOf(String.valueOf(object)).booleanValue(); 822 | } else if (type == Float.class) { 823 | object = Float.valueOf(String.valueOf(object)); 824 | } else if (type == float.class) { 825 | object = Float.valueOf(String.valueOf(object)).floatValue(); 826 | } else { 827 | if (object instanceof JSON) { 828 | //是json 829 | object = JSONObject.parseObject(((JSON) object).toJSONString(), protocolManager.getProtocolClazzORMethod().mClasses[i]); 830 | 831 | // object = ((JSON) object).toJavaObject(protocolManager.getProtocolClazzORMethod().mClasses[i]); 832 | } 833 | } 834 | } 835 | objs[i] = object; 836 | 837 | } else { 838 | objs[i] = DilutionsUtil.getParams(params_type[i]); 839 | } 840 | } 841 | Object object = method.invoke(obj,objs); 842 | data.setResult(object); 843 | // Log.i(TAG, "方法执行返回:" + object); 844 | } 845 | 846 | // Class[] typeArgs = new Class[1]; 847 | // typeArgs[0] = DilutionsData.class; 848 | // //TODO:需要做缓存优化处理? 849 | // //2017.3.29更新寻找super的方法 850 | // try { 851 | // method = clazz.getDeclaredMethod(methodName, typeArgs); 852 | // }catch (Exception e){ 853 | // e.printStackTrace(); 854 | //寻找父类的方法,因为有可能被调用方法存在于父类 855 | // Class round_clazz = clazz.getSuperclass(); 856 | // while(method == null && round_clazz != Object.class){ 857 | // method = findMethod(round_clazz, methodName, typeArgs); 858 | // round_clazz = round_clazz.getSuperclass(); 859 | // } 860 | // } 861 | // if(method == null){ 862 | // throw new Exception("dilutions could't find method, method is null"); 863 | // } 864 | // DilutionsMethodData dilutionsMethodData = new DilutionsMethodData(obj, method); 865 | // methodMap.put(path, dilutionsMethodData); 866 | // } 867 | // DilutionsMethodData methodData = methodMap.get(path); 868 | // dilutionsMethodData.method.invoke(dilutionsMethodData.obj, data); 869 | } 870 | // }catch (Exception e){ 871 | // e.printStackTrace(); 872 | // } 873 | 874 | //callback 875 | if(callBack != null){ 876 | callBack.onDilutions(data); 877 | } 878 | 879 | if(mDilutionsGlobalListener != null){ 880 | mDilutionsGlobalListener.onCallBack(data); 881 | } 882 | 883 | } 884 | 885 | private Method findMethod(Class clazz, String name, Class... parameterTypes){ 886 | try { 887 | return clazz.getDeclaredMethod(name, parameterTypes); 888 | } catch (NoSuchMethodException e) { 889 | e.printStackTrace(); 890 | } 891 | return null; 892 | } 893 | 894 | /** 895 | * 获得builder 896 | * @return 897 | */ 898 | DilutionsBuilder getDilutionsBuilder(){ 899 | return new DilutionsBuilder(mContext); 900 | } 901 | 902 | /** 903 | * 获得context 904 | * @return 905 | */ 906 | public Context getContext(){ 907 | return mContext; 908 | } 909 | } 910 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/DilutionsManager.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | /** 4 | * Created by Linhh on 16/12/1. 5 | */ 6 | 7 | public interface DilutionsManager { 8 | 9 | public void apply() throws Exception; 10 | 11 | public DilutionsBuilder getDilutionsBuilder(); 12 | 13 | public ProtocolClazzORMethod getProtocolClazzORMethod(); 14 | 15 | public int getProtocolType(); 16 | } 17 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/DilutionsValue.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | /** 4 | * Created by Linhh on 16/9/5. 5 | */ 6 | public class DilutionsValue { 7 | public static final int DEFAULT_VALUE = -1; 8 | public static final String VAL_PARAMS = "params"; 9 | 10 | public static final int PROTOCOL_DEFAULT = 0; 11 | public static final int PROTOCOL_JUMP = 1; 12 | public static final int PROTOCOL_METHOD = 2; 13 | 14 | public static final int DILUTIONS_NO = 0;//不来自dilutions 15 | public static final int DILUTIONS_PROXY = 1;//来自代理 16 | public static final int DILUTIONS_HTTP = 2;//来自WEBVIEW 17 | public static final String DILUTIONS_METHOD_EXTRA = "dilutions_method_params_extra"; 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/FieldHanlder.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | import android.os.Bundle; 4 | 5 | import com.alibaba.fastjson.JSON; 6 | import com.alibaba.fastjson.JSONObject; 7 | import com.linhonghong.dilutions.utils.DilutionsUtil; 8 | 9 | import java.lang.reflect.Field; 10 | 11 | /** 12 | * Created by Linhh on 16/9/2. 13 | */ 14 | abstract class FieldHandler { 15 | abstract void apply(Object object, Bundle bundle) throws Exception; 16 | abstract String name(); 17 | 18 | static final class ExtraHandler extends FieldHandler { 19 | private final Field field; 20 | private final String name; 21 | public ExtraHandler(Field field, String name){ 22 | this.field = field; 23 | this.name = name; 24 | } 25 | 26 | @Override 27 | void apply(Object object, Bundle bundle) throws Exception { 28 | Object key = bundle.get(name); 29 | if(key != null) { 30 | field.setAccessible(true); 31 | field.set(object, key); 32 | } 33 | } 34 | 35 | @Override 36 | String name() { 37 | return this.name; 38 | } 39 | } 40 | 41 | static final class FragmentargHandler extends FieldHandler { 42 | private final Field field; 43 | private final String name; 44 | public FragmentargHandler(Field field, String name){ 45 | this.field = field; 46 | this.name = name; 47 | } 48 | 49 | @Override 50 | void apply(Object object, Bundle bundle) throws Exception { 51 | String jsonParam = bundle.getString(DilutionsInstrument.URI_CALL_PARAM); 52 | if(DilutionsUtil.isNull(jsonParam)){ 53 | //没有找到json 54 | Object key = bundle.get(name); 55 | if(key != null) { 56 | field.setAccessible(true); 57 | field.set(object, key); 58 | } 59 | return; 60 | } 61 | JSONObject jsonObject = JSON.parseObject(jsonParam); 62 | if(jsonObject == null){ 63 | //转换失败 64 | return; 65 | } 66 | jsonObject = jsonObject.getJSONObject(DilutionsValue.VAL_PARAMS); 67 | if(jsonObject == null){ 68 | return; 69 | } 70 | Object key = jsonObject.get(name); 71 | 72 | if(key != null) { 73 | if(key instanceof JSONObject){ 74 | //转换为对象 75 | key = JSON.parseObject(jsonObject.get(name).toString(),field.getType()); 76 | } 77 | field.setAccessible(true); 78 | field.set(object, key); 79 | } 80 | } 81 | 82 | @Override 83 | String name() { 84 | return this.name; 85 | } 86 | } 87 | 88 | static final class ActivityProtocolExtraHandler extends FieldHandler { 89 | private final Field field; 90 | private final String name; 91 | public ActivityProtocolExtraHandler(Field field, String name){ 92 | this.field = field; 93 | this.name = name; 94 | } 95 | 96 | @Override 97 | void apply(Object object, Bundle bundle) throws Exception { 98 | //获取传递的json 99 | String jsonParam = bundle.getString(DilutionsInstrument.URI_CALL_PARAM); 100 | if(DilutionsUtil.isNull(jsonParam)){ 101 | //没有找到json 102 | return; 103 | } 104 | JSONObject jsonObject = JSON.parseObject(jsonParam); 105 | if(jsonObject == null){ 106 | //转换失败 107 | return; 108 | } 109 | jsonObject = jsonObject.getJSONObject(DilutionsValue.VAL_PARAMS); 110 | if(jsonObject == null){ 111 | return; 112 | } 113 | Object key = jsonObject.get(name); 114 | 115 | if(key != null) { 116 | if(key instanceof JSONObject){ 117 | //转换为对象 118 | key = JSON.parseObject(jsonObject.get(name).toString(),field.getType()); 119 | } 120 | field.setAccessible(true); 121 | field.set(object, key); 122 | } 123 | } 124 | 125 | @Override 126 | String name() { 127 | return this.name; 128 | } 129 | } 130 | 131 | static final class ActivityProtocolFromHandler extends FieldHandler { 132 | private final Field field; 133 | private final String name; 134 | public ActivityProtocolFromHandler(Field field, String name){ 135 | this.field = field; 136 | this.name = name; 137 | } 138 | 139 | @Override 140 | void apply(Object object, Bundle bundle) throws Exception { 141 | //获取传递的path 142 | String path = bundle.getString(DilutionsInstrument.URI_FROM); 143 | field.setAccessible(true); 144 | field.set(object, path); 145 | } 146 | 147 | @Override 148 | String name() { 149 | return this.name; 150 | } 151 | } 152 | 153 | static final class ActivityProtocolPathHandler extends FieldHandler { 154 | private final Field field; 155 | private final String name; 156 | public ActivityProtocolPathHandler(Field field, String name){ 157 | this.field = field; 158 | this.name = name; 159 | } 160 | 161 | @Override 162 | void apply(Object object, Bundle bundle) throws Exception { 163 | //获取传递的path 164 | String path = bundle.getString(DilutionsInstrument.URI_CALL_PATH); 165 | field.setAccessible(true); 166 | field.set(object, path); 167 | } 168 | 169 | @Override 170 | String name() { 171 | return this.name; 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/HttpProtocolManager.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | import android.net.Uri; 4 | 5 | import com.alibaba.fastjson.JSON; 6 | import com.alibaba.fastjson.JSONObject; 7 | import com.linhonghong.dilutions.utils.DilutionsUtil; 8 | 9 | import java.net.URLDecoder; 10 | import java.util.ArrayList; 11 | import java.util.HashMap; 12 | 13 | /** 14 | * Created by Linhh on 16/12/1. 15 | */ 16 | 17 | public class HttpProtocolManager implements DilutionsManager { 18 | 19 | private final static String TAG = HttpProtocolManager.class.getSimpleName(); 20 | 21 | //基础数据 22 | ArrayList> parameterHandlers; 23 | ProtocolClazzORMethod protocolClazzORMethod;//跳转目标 24 | DilutionsBuilder dilutionsBuilder; 25 | int protocolType; 26 | String methodName; 27 | 28 | // String[] args; 29 | 30 | HttpProtocolManager(Builder builder) { 31 | this.protocolType = builder.protocolType; 32 | this.parameterHandlers = builder.parameterHandlers; 33 | this.protocolClazzORMethod = builder.protocolClazzORMethod; 34 | this.methodName = builder.protocolClazzORMethod.methodName; 35 | this.dilutionsBuilder = builder.dilutionsBuilder; 36 | } 37 | 38 | /** 39 | * 生效请求配置 40 | * @throws Exception 41 | */ 42 | public void apply() throws Exception{ 43 | for(int i = 0; i < parameterHandlers.size(); i ++){ 44 | parameterHandlers.get(i).apply(dilutionsBuilder); 45 | } 46 | } 47 | 48 | public ProtocolClazzORMethod getProtocolClazzORMethod(){ 49 | return protocolClazzORMethod; 50 | } 51 | 52 | @Override 53 | public int getProtocolType() { 54 | return protocolType; 55 | } 56 | 57 | public DilutionsBuilder getDilutionsBuilder(){ 58 | return dilutionsBuilder; 59 | } 60 | 61 | static final class Builder { 62 | 63 | final DilutionsInstrument instrument; 64 | 65 | ProtocolClazzORMethod protocolClazzORMethod;//跳转目标 66 | 67 | //参数 68 | ArrayList> parameterHandlers; 69 | 70 | DilutionsBuilder dilutionsBuilder; 71 | 72 | Uri uri; 73 | 74 | HashMap mExtraMap; 75 | 76 | int protocolType = DilutionsValue.PROTOCOL_DEFAULT;//协议类型,如若在解析过程中始终保持default状态就会报错 77 | 78 | public Builder(DilutionsInstrument instrument, Uri uri, HashMap map) { 79 | this.instrument = instrument; 80 | this.uri = uri; 81 | this.dilutionsBuilder = instrument.getDilutionsBuilder(); 82 | this.mExtraMap = map; 83 | } 84 | 85 | /** 86 | * 解析方法注解 87 | * @param uri 88 | */ 89 | private void parseUri(Uri uri) throws Exception{ 90 | if(uri == null){ 91 | throw new Exception("URI 协议为空, 解析失败"); 92 | } 93 | 94 | // LogUtils.d(TAG, " Dilutions获取到http协议: " + uri.toString()); 95 | 96 | String host = uri.getHost(); 97 | String scheme = uri.getScheme(); 98 | String path = uri.getPath(); 99 | String query = uri.getQuery(); 100 | 101 | if (scheme == null || scheme.trim().equals("")) { 102 | throw new Exception("scheme为空, 解析失败"); 103 | } 104 | 105 | //合法性检查 106 | // if(!instrument.checkUriSafe(scheme, path)){ 107 | // throw new Exception("协议不合法"); 108 | // } 109 | 110 | //获得该URI的类型 111 | protocolType = instrument.getUriType(scheme, path); 112 | 113 | parserParams(protocolType, path, query); 114 | 115 | parseMethodPath(protocolType, path); 116 | 117 | if(mExtraMap != null){ 118 | parseParameter(protocolType, path, mExtraMap); 119 | } 120 | } 121 | 122 | /** 123 | * 解析参数 124 | * @param path 125 | * @param query 126 | * @return 127 | */ 128 | public void parserParams(int protocolType, String path, String query) throws Exception{ 129 | // Map queryPairs = new LinkedHashMap<>(); 130 | if (DilutionsUtil.isNull(query)) { 131 | // throw new Exception("dilutions protocol query is null"); 132 | return; 133 | } 134 | String[] pairs = query.split("&"); 135 | for (String pair : pairs) { 136 | int idx = pair.indexOf("="); 137 | String key = URLDecoder.decode(pair.substring(0, idx), "UTF-8"); 138 | if(DilutionsUtil.isEqual("params", key)) { 139 | // String value = URLDecoder.decode(pair.substring(idx + 1), "UTF-8"); 140 | // byte[] decodeBytes = Base64.decode(value, Base64.DEFAULT); 141 | String value = pair.substring(idx + 1); 142 | value = DilutionsUtil.base64UrlDecode(value); 143 | // queryPairs.put(key, value); 144 | // queryPairs.get("params") 145 | 146 | parseParameter(protocolType, path, value); 147 | } 148 | //如果有额外的参数请添加于此 149 | 150 | } 151 | } 152 | 153 | /** 154 | * 根据名字找到API 155 | * @param value 156 | * @param protocolType 协议类型 157 | */ 158 | private void parseMethodPath(int protocolType, String value) throws Exception{ 159 | 160 | protocolClazzORMethod = instrument.getClazz(protocolType, value); 161 | 162 | if(protocolClazzORMethod.clazz == null){ 163 | //错误 164 | throw new Exception("clazz is null"); 165 | } 166 | 167 | //设置dilutions的跳转类,因为intent会被重新创建,所以这里要复用设置 168 | dilutionsBuilder.setClazz(protocolType, value, protocolClazzORMethod); 169 | 170 | } 171 | 172 | public HttpProtocolManager build() throws Exception{ 173 | //存储参数处理器 174 | parameterHandlers = new ArrayList<>(); 175 | 176 | parseUri(uri); 177 | 178 | dilutionsBuilder.setFrom(DilutionsValue.DILUTIONS_HTTP);//代理跳转 179 | 180 | dilutionsBuilder.setUri(uri); 181 | 182 | return new HttpProtocolManager(this); 183 | } 184 | 185 | private void parseParameter(int protocolType, String path, HashMap value) throws Exception{ 186 | JSONObject jsonObject = new JSONObject(value);//将参数转换为json 187 | //构造参数处理器 188 | instrument.createExtraParams( 189 | parameterHandlers, 190 | path, 191 | jsonObject); 192 | //没有能识别的参数,如果出现这个说明出错了 193 | } 194 | 195 | private void parseParameter(int protocolType, String path, String value) throws Exception{ 196 | JSONObject jsonObject = JSON.parseObject(value);//将参数转换为json 197 | //构造参数处理器 198 | instrument.createExtraParams( 199 | parameterHandlers, 200 | path, 201 | jsonObject); 202 | //没有能识别的参数,如果出现这个说明出错了 203 | } 204 | } 205 | } 206 | 207 | /** 208 | * 协议处理器封装类 209 | */ 210 | class ProtocolClazzORMethod{ 211 | public String mPath; 212 | public Class clazz; 213 | public String methodName; 214 | public ArrayList mParamsList; 215 | public Class[] mClasses; 216 | public ProtocolClazzORMethod(Class clazz, String methodName, String path, ArrayList paramsList,Class[] classes){ 217 | this.clazz = clazz; 218 | this.methodName = methodName; 219 | this.mPath = path; 220 | this.mParamsList = paramsList; 221 | this.mClasses = classes; 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/ParameterHanlder.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | import com.linhonghong.dilutions.utils.DilutionsUtil; 4 | 5 | /** 6 | * Created by Linhh on 16/11/30. 7 | */ 8 | 9 | public abstract class ParameterHanlder { 10 | abstract void apply(DilutionsBuilder builder) throws Exception; 11 | abstract void setValue(Object value); 12 | abstract String getName(); 13 | abstract void setType(Class type); 14 | abstract void setPassNull(boolean nullIgnore); 15 | 16 | static final class ExtraParams extends ParameterHanlder { 17 | private final String name; 18 | 19 | private Object value; 20 | private Class type; 21 | 22 | public boolean passnull = false;//用于判断是否提交空该字段 23 | 24 | ExtraParams(String name){ 25 | this.name = name; 26 | } 27 | 28 | ExtraParams(String name, Object value) { 29 | this.name = name; 30 | this.value = value; 31 | } 32 | 33 | 34 | @Override void apply(DilutionsBuilder builder) throws Exception { 35 | //为null做处理,方便那些懒惰的程序员 36 | if(passnull){ 37 | if(value instanceof String && DilutionsUtil.isNull(String.valueOf(value))){ 38 | return; 39 | } 40 | if(value == null){ 41 | return; 42 | //如果是nullIgnore并且该字段为空则不提交该字段 43 | } 44 | } 45 | builder.addParams(name, DilutionsUtil.formatString(value), type); 46 | } 47 | 48 | @Override 49 | void setValue(Object value) { 50 | this.value = value; 51 | } 52 | 53 | @Override 54 | String getName() { 55 | return name; 56 | } 57 | 58 | @Override 59 | void setType(Class type) { 60 | this.type = type; 61 | } 62 | 63 | @Override 64 | void setPassNull(boolean passnull) { 65 | this.passnull = passnull; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/ProtocolManager.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions; 2 | 3 | import android.content.Intent; 4 | 5 | import com.linhonghong.dilutions.annotations.ExtraParam; 6 | import com.linhonghong.dilutions.annotations.PassNull; 7 | import com.linhonghong.dilutions.annotations.ProtocolPath; 8 | import com.linhonghong.dilutions.utils.Checker; 9 | 10 | import java.lang.annotation.Annotation; 11 | import java.lang.reflect.Method; 12 | import java.lang.reflect.Type; 13 | import java.util.ArrayList; 14 | import java.util.HashMap; 15 | 16 | /** 17 | * 协议管理器 18 | * Created by Linhh on 16/11/30. 19 | */ 20 | public class ProtocolManager implements DilutionsManager { 21 | 22 | //基础数据 23 | ArrayList> parameterHandlers; 24 | int methodIndex = 0; 25 | int protocolType; 26 | DilutionsBuilder dilutionsBuilder; 27 | ProtocolClazzORMethod protocolClazzORMethod; 28 | 29 | // String[] args; 30 | 31 | ProtocolManager(Builder builder) { 32 | this.parameterHandlers = builder.parameterHandlers; 33 | this.methodIndex = builder.methodIndex; 34 | this.protocolClazzORMethod = builder.protocolClazzORMethod; 35 | this.protocolType = builder.protocolType; 36 | this.dilutionsBuilder = builder.dilutionsBuilder; 37 | } 38 | 39 | /** 40 | * 生效请求配置 41 | * @throws Exception 42 | */ 43 | public void apply() throws Exception{ 44 | for(int i = methodIndex; i < parameterHandlers.size(); i ++){ 45 | parameterHandlers.get(i).apply(dilutionsBuilder); 46 | } 47 | } 48 | 49 | @Override 50 | public DilutionsBuilder getDilutionsBuilder() { 51 | return dilutionsBuilder; 52 | } 53 | 54 | @Override 55 | public ProtocolClazzORMethod getProtocolClazzORMethod() { 56 | return protocolClazzORMethod; 57 | } 58 | 59 | @Override 60 | public int getProtocolType() { 61 | return protocolType; 62 | } 63 | 64 | public Intent intent(){ 65 | return dilutionsBuilder.getDilutionsData().getIntent(); 66 | } 67 | 68 | /** 69 | * 设置值 70 | * @param args 71 | */ 72 | public void args(Object... args){ 73 | //保存数据 74 | for(int i = methodIndex, x = 0 ; i < parameterHandlers.size(); i ++, x ++){ 75 | parameterHandlers.get(i).setValue(args[x]); 76 | } 77 | } 78 | 79 | /** 80 | * 网络协议 81 | * @param map 82 | */ 83 | public void args(HashMap map){ 84 | //保存数据 85 | for(int i = methodIndex, x = 0 ; i < parameterHandlers.size(); i ++, x ++){ 86 | ParameterHanlder parameterHanlder = parameterHandlers.get(i); 87 | parameterHandlers.get(i).setValue(map.get(parameterHanlder.getName())); 88 | } 89 | } 90 | 91 | static final class Builder { 92 | 93 | final DilutionsInstrument instrument; 94 | final Method method; 95 | final Annotation[] methodAnnotations; 96 | final Annotation[][] parameterAnnotationsArray; 97 | final Type[] parameterTypes; 98 | 99 | ProtocolClazzORMethod protocolClazzORMethod;//跳转目标 100 | 101 | //参数 102 | ArrayList> parameterHandlers; 103 | 104 | DilutionsBuilder dilutionsBuilder; 105 | 106 | //保存方法所有的注解数量 107 | int methodIndex = 0; 108 | 109 | int protocolType = DilutionsValue.PROTOCOL_JUMP; 110 | 111 | public Builder(DilutionsInstrument instrument, Method method) { 112 | this.instrument = instrument; 113 | this.method = method; 114 | //方法注解 115 | this.methodAnnotations = method.getAnnotations(); 116 | //获得参数类型 117 | this.parameterTypes = method.getGenericParameterTypes(); 118 | //参数注解 119 | this.parameterAnnotationsArray = method.getParameterAnnotations(); 120 | 121 | this.dilutionsBuilder = instrument.getDilutionsBuilder(); 122 | } 123 | 124 | /** 125 | * 解析方法注解 126 | * @param annotation 127 | */ 128 | private void parseMethodAnnotation(Annotation annotation) throws Exception{ 129 | if (annotation instanceof ProtocolPath) { 130 | parseMethodPath(((ProtocolPath) annotation).value()); 131 | } 132 | } 133 | 134 | /** 135 | * 根据名字找到API 136 | * @param value 137 | */ 138 | private void parseMethodPath(String value) throws Exception{ 139 | 140 | protocolType = instrument.getUriType(value); 141 | 142 | protocolClazzORMethod = instrument.getClazz(protocolType, value); 143 | 144 | if(protocolClazzORMethod == null){ 145 | //错误 146 | throw methodError("clazz is null"); 147 | } 148 | 149 | //设置dilutions的跳转类 150 | dilutionsBuilder.setClazz(protocolType, value, protocolClazzORMethod); 151 | 152 | } 153 | 154 | public ProtocolManager build() { 155 | //存储参数处理器 156 | parameterHandlers = new ArrayList<>(); 157 | 158 | //解析当前方法的所有annotation 159 | for (Annotation annotation : methodAnnotations) { 160 | //当前只会有一个api,所以实际上不需要for循环 161 | try { 162 | parseMethodAnnotation(annotation); 163 | } catch (Exception e) { 164 | e.printStackTrace(); 165 | } 166 | } 167 | 168 | methodIndex = parameterHandlers.size(); 169 | 170 | //解析参数annotation 171 | int parameterCount = parameterAnnotationsArray.length; 172 | // int annotationsCount = 0; 173 | //计算annotations数量。实际上需要这个吗?这里可以优化,但这里不这样做很容易oob 174 | // for(int i = 0 ; i < parameterCount; i ++){ 175 | // if(parameterAnnotationsArray[i].length > 0) { 176 | // annotationsCount ++; 177 | // } 178 | // } 179 | //真实计算 180 | for (int p = 0; p < parameterCount; p++) { 181 | //获取参数数据类型 182 | Type parameterType = parameterTypes[p]; 183 | //判断是否是不能处理的数据 184 | if (Checker.hasUnresolvableType(parameterType)) { 185 | throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s", 186 | parameterType); 187 | } 188 | 189 | //当前参数的annotation 190 | Annotation[] parameterAnnotations = parameterAnnotationsArray[p]; 191 | if (parameterAnnotations == null) { 192 | throw parameterError(p, "No annotation found."); 193 | } 194 | 195 | // if(parameterAnnotationsArray[p].length > 0) { 196 | //这是个annotations,解析 197 | ParameterHanlder parameterHandler = parseParameter(p, parameterType, parameterAnnotations); 198 | parameterHandlers.add(parameterHandler); 199 | // annotationsCount ++; 200 | // } 201 | // else{ 202 | // //非annotations 203 | // parameterHandlers[p] = null; 204 | // } 205 | } 206 | 207 | dilutionsBuilder.setFrom(DilutionsValue.DILUTIONS_PROXY);//代理跳转 208 | 209 | return new ProtocolManager(this); 210 | } 211 | 212 | private ParameterHanlder parseParameterAnnotation( 213 | int p, Type type, Annotation annotation) { 214 | if (annotation instanceof ExtraParam) { 215 | //解析Get参数 216 | ExtraParam query = (ExtraParam) annotation; 217 | String name = query.value(); 218 | //暂时不支持数组类型,如果需要数组在增加 219 | Class rawParameterType = Checker.getRawType(type); 220 | if (Iterable.class.isAssignableFrom(rawParameterType)) { 221 | //TODO:实现数组 222 | throw parameterError(p, "not support array current"); 223 | } else if (rawParameterType.isArray()) { 224 | //TODO:实现数组 225 | throw parameterError(p, "not support array current"); 226 | } else { 227 | //获取真实参数 228 | // name = instrument.getParams(protocolType, name, protocolClazzORMethod.mPath); 229 | ParameterHanlder.ExtraParams parameterHandler = new ParameterHanlder.ExtraParams<>(name); 230 | parameterHandler.setType(rawParameterType); 231 | return parameterHandler; 232 | } 233 | 234 | } 235 | //没有能识别的参数,如果出现这个说明出错了 236 | return null; 237 | } 238 | 239 | private ParameterHanlder parseParameter( 240 | int p, Type parameterType, Annotation[] annotations) { 241 | ParameterHanlder result = null; 242 | boolean nullignore = false; 243 | for (Annotation annotation : annotations) { 244 | if (annotation instanceof PassNull) { 245 | //如果是nullignore 246 | nullignore = true; 247 | continue; 248 | } 249 | ParameterHanlder annotationAction = parseParameterAnnotation( 250 | p, parameterType, annotation); 251 | 252 | if (annotationAction == null) { 253 | continue; 254 | } 255 | 256 | if (result != null) { 257 | //重复annotations 258 | throw parameterError(p, "only support one annotations"); 259 | } 260 | 261 | result = annotationAction; 262 | } 263 | 264 | if (result == null) { 265 | throw parameterError(p, "No annotation found"); 266 | } 267 | 268 | result.setPassNull(nullignore); 269 | 270 | return result; 271 | } 272 | 273 | private RuntimeException methodError(String message, Object... args) { 274 | return methodError(null, message, args); 275 | } 276 | 277 | private RuntimeException methodError(Throwable cause, String message, Object... args) { 278 | message = String.format(message, args); 279 | return new IllegalArgumentException(message 280 | + "\n for method " 281 | + method.getDeclaringClass().getSimpleName() 282 | + "." 283 | + method.getName(), cause); 284 | } 285 | 286 | private RuntimeException parameterError(int p, String message, Object... args) { 287 | return methodError(message + " (parameter #" + (p + 1) + ")", args); 288 | } 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/ActivityExtra.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.FIELD; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 16/9/2. 12 | */ 13 | @Documented 14 | @Target(FIELD) 15 | @Retention(RUNTIME) 16 | public @interface ActivityExtra { 17 | String value() default ""; 18 | } 19 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/ActivityProtocol.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.Target; 7 | 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 16/12/1. 12 | */ 13 | @Documented 14 | @Retention(RUNTIME) 15 | @Target(ElementType.TYPE) 16 | public @interface ActivityProtocol { 17 | String[] value() default ""; 18 | } 19 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/ActivityProtocolExtra.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.FIELD; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 16/11/30. 12 | */ 13 | @Documented 14 | @Target(FIELD) 15 | @Retention(RUNTIME) 16 | public @interface ActivityProtocolExtra { 17 | String value() default ""; 18 | } 19 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/ActivityProtocolPath.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.FIELD; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 16/11/30. 12 | */ 13 | @Documented 14 | @Target(FIELD) 15 | @Retention(RUNTIME) 16 | public @interface ActivityProtocolPath { 17 | String value() default ""; 18 | } 19 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/CustomAnimation.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.Target; 7 | 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 16/12/1. 12 | */ 13 | @Documented 14 | @Retention(RUNTIME) 15 | @Target(ElementType.TYPE) 16 | public @interface CustomAnimation { 17 | int enter() default 0; 18 | int exit() default 0; 19 | } 20 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/ExtraParam.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.PARAMETER; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 16/11/29. 12 | */ 13 | @Documented 14 | @Target(PARAMETER) 15 | @Retention(RUNTIME) 16 | public @interface ExtraParam { 17 | String value() default ""; 18 | } 19 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/FragmentArg.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.FIELD; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 16/9/2. 12 | */ 13 | @Documented 14 | @Target(FIELD) 15 | @Retention(RUNTIME) 16 | public @interface FragmentArg { 17 | String value() default ""; 18 | } -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/MethodExtra.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import com.linhonghong.dilutions.DilutionsValue; 4 | 5 | import java.lang.annotation.Documented; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.Target; 8 | 9 | import static java.lang.annotation.ElementType.PARAMETER; 10 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 11 | 12 | /** 13 | * Created by Linhh on 09/02/2018. 14 | */ 15 | @Documented 16 | @Target(PARAMETER) 17 | @Retention(RUNTIME) 18 | public @interface MethodExtra { 19 | String value() default DilutionsValue.DILUTIONS_METHOD_EXTRA; 20 | } 21 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/MethodParam.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.PARAMETER; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 2017/7/19. 12 | */ 13 | @Documented 14 | @Target(PARAMETER) 15 | @Retention(RUNTIME) 16 | public @interface MethodParam { 17 | String value() default ""; 18 | } 19 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/MethodProtocol.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.METHOD; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 17/6/22. 12 | */ 13 | 14 | @Documented 15 | @Target(METHOD) 16 | @Retention(RUNTIME) 17 | public @interface MethodProtocol { 18 | String value() default ""; 19 | } -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/Param.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.PARAMETER; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 17/6/22. 12 | */ 13 | 14 | @Documented 15 | @Target(PARAMETER) 16 | @Retention(RUNTIME) 17 | public @interface Param { 18 | String value() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/PassNull.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.PARAMETER; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 16/11/30. 12 | */ 13 | @Documented 14 | @Target(PARAMETER) 15 | @Retention(RUNTIME) 16 | public @interface PassNull { 17 | } 18 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/ProtocolFrom.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.FIELD; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 16/12/23. 12 | */ 13 | @Documented 14 | @Target(FIELD) 15 | @Retention(RUNTIME) 16 | public @interface ProtocolFrom { 17 | String value() default ""; 18 | } 19 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/annotations/ProtocolPath.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.METHOD; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Created by Linhh on 16/11/29. 12 | */ 13 | @Documented 14 | @Target(METHOD) 15 | @Retention(RUNTIME) 16 | public @interface ProtocolPath { 17 | String value() default ""; 18 | } 19 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/data/DilutionsConfig.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.data; 2 | 3 | import com.linhonghong.dilutions.interfaces.DilutionsCallBack; 4 | import com.linhonghong.dilutions.interfaces.DilutionsInterceptor; 5 | 6 | /** 7 | * Created by Linhh on 16/12/16. 8 | */ 9 | 10 | public class DilutionsConfig { 11 | 12 | private DilutionsCallBack mDilutionsCallBack; 13 | private DilutionsInterceptor mDilutionsInterceptor; 14 | private T mWhat; 15 | 16 | private DilutionsConfig(Builder builder){ 17 | this.mDilutionsCallBack = builder.mDilutionsCallBack; 18 | this.mDilutionsInterceptor = builder.mDilutionsInterceptor; 19 | this.mWhat = builder.mWhat; 20 | } 21 | 22 | public DilutionsCallBack getDilutionsCallBack() { 23 | return mDilutionsCallBack; 24 | } 25 | 26 | public DilutionsInterceptor getDilutionsInterceptor() { 27 | return mDilutionsInterceptor; 28 | } 29 | 30 | public T getWhat() { 31 | return mWhat; 32 | } 33 | 34 | public static class Builder { 35 | private DilutionsCallBack mDilutionsCallBack; 36 | private DilutionsInterceptor mDilutionsInterceptor; 37 | private T mWhat; 38 | 39 | Builder() { 40 | // Doesn't use a setter as always required. 41 | } 42 | 43 | public Builder setDilutionsCallBack(DilutionsCallBack callBack){ 44 | mDilutionsCallBack = callBack; 45 | return this; 46 | } 47 | 48 | public Builder setDilutionsInterceptor(DilutionsInterceptor interceptor){ 49 | mDilutionsInterceptor = interceptor; 50 | return this; 51 | } 52 | 53 | public Builder setWhat(T what){ 54 | mWhat = what; 55 | return this; 56 | } 57 | 58 | public DilutionsConfig build(){ 59 | return new DilutionsConfig(this); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/data/DilutionsConfigFactory.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.data; 2 | 3 | import com.linhonghong.dilutions.interfaces.DilutionsCallBack; 4 | import com.linhonghong.dilutions.interfaces.DilutionsInterceptor; 5 | 6 | /** 7 | * Created by Linhh on 16/12/16. 8 | */ 9 | 10 | public class DilutionsConfigFactory { 11 | public static DilutionsConfig.Builder newBuilder(DilutionsCallBack dilutionsCallBack, DilutionsInterceptor interceptor, T what) { 12 | return new DilutionsConfig.Builder() 13 | .setDilutionsCallBack(dilutionsCallBack) 14 | .setDilutionsInterceptor(interceptor) 15 | .setWhat(what); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/data/DilutionsData.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.data; 2 | 3 | import android.content.Intent; 4 | import android.net.Uri; 5 | 6 | import java.util.ArrayList; 7 | 8 | /** 9 | * 数据包裹处理器 10 | * Created by Linhh on 16/12/16. 11 | */ 12 | 13 | public class DilutionsData { 14 | private Intent mIntent; 15 | private T what; 16 | private Uri mUri; 17 | private Object mResult; 18 | private ArrayList mList; 19 | public Intent getIntent(){ 20 | return mIntent; 21 | } 22 | 23 | public void setList(ArrayList list){ 24 | mList = list; 25 | } 26 | 27 | public ArrayList getList(){ 28 | return mList; 29 | } 30 | 31 | public T getWhat(){ 32 | return what; 33 | } 34 | 35 | public void setIntent(Intent intent){ 36 | mIntent = intent; 37 | } 38 | 39 | public void setUri(Uri uri){ 40 | mUri = uri; 41 | } 42 | 43 | public void setResult(Object result){ 44 | mResult = result; 45 | } 46 | 47 | public Object getResult(){ 48 | return mResult; 49 | } 50 | 51 | public Uri getUri(){ 52 | return mUri; 53 | } 54 | 55 | public void setWhat(T what){ 56 | this.what = what; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/data/DilutionsGlobalListener.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.data; 2 | 3 | /** 4 | * Created by Linhh on 2017/7/10. 5 | */ 6 | 7 | public interface DilutionsGlobalListener { 8 | public boolean onCheckUri(String uri); 9 | 10 | public boolean onUnSupportUri(String uri); 11 | 12 | public boolean onIntercept(DilutionsData data); 13 | 14 | public boolean onCallBack(DilutionsData data); 15 | } 16 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/data/DilutionsMethodData.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.data; 2 | 3 | 4 | import java.lang.reflect.Method; 5 | 6 | /** 7 | * Created by Linhh on 16/12/23. 8 | */ 9 | 10 | public class DilutionsMethodData { 11 | public Object obj; 12 | public Method method; 13 | public DilutionsMethodData(Object obj, Method method){ 14 | this.obj = obj; 15 | this.method = method; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/interfaces/DilutionsCallBack.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.interfaces; 2 | 3 | import com.linhonghong.dilutions.data.DilutionsData; 4 | 5 | /** 6 | * 回调处理器 7 | * Created by Linhh on 16/12/16. 8 | */ 9 | 10 | public interface DilutionsCallBack { 11 | public void onDilutions(DilutionsData data); 12 | } 13 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/interfaces/DilutionsInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.interfaces; 2 | 3 | import com.linhonghong.dilutions.data.DilutionsData; 4 | 5 | /** 6 | * 数据拦截 7 | * Created by Linhh on 16/12/16. 8 | */ 9 | 10 | public interface DilutionsInterceptor { 11 | public boolean interceptor(DilutionsData data); 12 | } 13 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/interfaces/DilutionsPathInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.interfaces; 2 | 3 | /** 4 | * Created by Linhh on 2017/8/11. 5 | */ 6 | 7 | public abstract class DilutionsPathInterceptor implements DilutionsInterceptor{ 8 | 9 | public final static int LEVEL_NORMAL = 0; 10 | 11 | public int level(){ 12 | return LEVEL_NORMAL; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/utils/Checker.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.utils; 2 | 3 | import java.lang.reflect.Array; 4 | import java.lang.reflect.GenericArrayType; 5 | import java.lang.reflect.ParameterizedType; 6 | import java.lang.reflect.Type; 7 | import java.lang.reflect.TypeVariable; 8 | import java.lang.reflect.WildcardType; 9 | 10 | /** 11 | * Created by Linhh on 16/8/25. 12 | */ 13 | public class Checker { 14 | /** 15 | * 判断一个manager是否是接口 16 | * @param service 17 | * @param 18 | */ 19 | public static void validateManagerInterface(Class service) { 20 | if (!service.isInterface()) { 21 | throw new IllegalArgumentException("Service declarations must be interfaces."); 22 | } 23 | if (service.getInterfaces().length > 0) { 24 | throw new IllegalArgumentException("Service interfaces must not extend other interfaces."); 25 | } 26 | } 27 | 28 | /** 29 | * 判断是否为不能处理的类型 30 | * @param type 31 | * @return 32 | */ 33 | public static boolean hasUnresolvableType(Type type) { 34 | if (type instanceof Class) { 35 | return false; 36 | } 37 | if (type instanceof ParameterizedType) { 38 | ParameterizedType parameterizedType = (ParameterizedType) type; 39 | for (Type typeArgument : parameterizedType.getActualTypeArguments()) { 40 | if (hasUnresolvableType(typeArgument)) { 41 | return true; 42 | } 43 | } 44 | return false; 45 | } 46 | if (type instanceof GenericArrayType) { 47 | return hasUnresolvableType(((GenericArrayType) type).getGenericComponentType()); 48 | } 49 | if (type instanceof TypeVariable) { 50 | return true; 51 | } 52 | if (type instanceof WildcardType) { 53 | return true; 54 | } 55 | String className = type == null ? "null" : type.getClass().getName(); 56 | throw new IllegalArgumentException("Expected a Class, ParameterizedType, or " 57 | + "GenericArrayType, but <" + type + "> is of type " + className); 58 | } 59 | 60 | public static Class getRawType(Type type) { 61 | if (type == null) throw new NullPointerException("type == null"); 62 | 63 | if (type instanceof Class) { 64 | // 普通的class 65 | return (Class) type; 66 | } 67 | if (type instanceof ParameterizedType) { 68 | ParameterizedType parameterizedType = (ParameterizedType) type; 69 | 70 | Type rawType = parameterizedType.getRawType(); 71 | if (!(rawType instanceof Class)) throw new IllegalArgumentException(); 72 | return (Class) rawType; 73 | } 74 | if (type instanceof GenericArrayType) { 75 | Type componentType = ((GenericArrayType) type).getGenericComponentType(); 76 | return Array.newInstance(getRawType(componentType), 0).getClass(); 77 | } 78 | if (type instanceof TypeVariable) { 79 | return Object.class; 80 | } 81 | if (type instanceof WildcardType) { 82 | return getRawType(((WildcardType) type).getUpperBounds()[0]); 83 | } 84 | 85 | throw new IllegalArgumentException("Expected a Class, ParameterizedType, or " 86 | + "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName()); 87 | } 88 | 89 | public static Type getParameterUpperBound(int index, ParameterizedType type) { 90 | Type[] types = type.getActualTypeArguments(); 91 | if (index < 0 || index >= types.length) { 92 | throw new IllegalArgumentException( 93 | "Index " + index + " not in range [0," + types.length + ") for " + type); 94 | } 95 | Type paramType = types[index]; 96 | if (paramType instanceof WildcardType) { 97 | return ((WildcardType) paramType).getUpperBounds()[0]; 98 | } 99 | return paramType; 100 | } 101 | 102 | public static T checkNotNull(T object, String message) { 103 | if (object == null) { 104 | throw new NullPointerException(message); 105 | } 106 | return object; 107 | } 108 | 109 | public static Type getCallResponseType(Type returnType) { 110 | if (!(returnType instanceof ParameterizedType)) { 111 | throw new IllegalArgumentException( 112 | "Call return type must be parameterized as Call or Call"); 113 | } 114 | return getParameterUpperBound(0, (ParameterizedType) returnType); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/utils/DilutionsUriBuilder.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.utils; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import android.text.TextUtils; 6 | import android.util.Base64; 7 | 8 | import com.alibaba.fastjson.JSONObject; 9 | import com.linhonghong.dilutions.DilutionsValue; 10 | 11 | import java.io.UnsupportedEncodingException; 12 | 13 | /** 14 | * Created by Linhh on 2017/7/28. 15 | */ 16 | 17 | public class DilutionsUriBuilder { 18 | 19 | /** 20 | * 构造通用的Uri 协议 21 | *

22 | * test linhonghong://dilutions/test 23 | * 24 | * @param path 如: group ,前面不要带"/" 25 | * @param param 26 | * @return 27 | */ 28 | public static String buildUri(String scheme, String path, JSONObject param) { 29 | String json = ""; 30 | if (param != null) { 31 | json = param.toString(); 32 | } 33 | 34 | return buildUri(scheme, path, json); 35 | } 36 | 37 | /********** 38 | * 私有方法 39 | **********/ 40 | 41 | public static String buildUri(String scheme, String path, String json) { 42 | String mHost = ""; 43 | if(!isNull(path) && path.startsWith("/")){ 44 | path = path.substring(1, path.length()); 45 | } 46 | String mPath = path; 47 | if(!isNull(scheme) && scheme.endsWith("://")){ 48 | scheme = scheme.substring(0, scheme.length() - 3); 49 | } 50 | String query = buildQuery(json); 51 | return scheme + ":" + "//" + mHost + "/" + mPath + "?" + query; 52 | } 53 | 54 | public static boolean isNull(String str) { 55 | try { 56 | if (str == null) { 57 | return true; 58 | } else if (str != null) { 59 | if (str.equals("") || str.equals("null") || str.equals("[]")) { 60 | return true; 61 | } else if (str.trim().equals("") || str.trim().equals("null")) { 62 | return true; 63 | } else { 64 | return false; 65 | } 66 | } else { 67 | return false; 68 | } 69 | } catch (Exception ex) { 70 | ex.printStackTrace(); 71 | } 72 | return true; 73 | 74 | } 75 | 76 | /** 77 | * 获取Query,需要进行 base64 编码 78 | * 79 | * @param jsonObject 80 | * @return 81 | */ 82 | private static String buildQuery(JSONObject jsonObject) { 83 | if (jsonObject == null) { 84 | return ""; 85 | } 86 | return buildQuery(jsonObject.toString()); 87 | } 88 | 89 | private static String buildQuery(String json) { 90 | if (TextUtils.isEmpty(json)) { 91 | return ""; 92 | } 93 | 94 | return DilutionsValue.VAL_PARAMS + "=" + base64UrlEncode(json); 95 | 96 | } 97 | 98 | /** 99 | * BASE64 编码,URL_SAFE 100 | * 101 | * @param input 102 | * @return 103 | */ 104 | @TargetApi(Build.VERSION_CODES.FROYO) 105 | public static String base64UrlEncode(String input) { 106 | String ENCODING = "UTF-8"; 107 | String result = null; 108 | byte[] b = Base64.encode(input.getBytes(), Base64.URL_SAFE); 109 | try { 110 | result = new String(b, ENCODING); 111 | } catch (UnsupportedEncodingException e) { 112 | e.printStackTrace(); 113 | } 114 | return result; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /Dilutions/src/main/java/com/linhonghong/dilutions/utils/DilutionsUtil.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.dilutions.utils; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.os.Build; 7 | import android.os.Bundle; 8 | import android.util.Base64; 9 | 10 | import com.linhonghong.dilutions.DilutionsInstrument; 11 | 12 | import org.json.JSONObject; 13 | 14 | import java.io.UnsupportedEncodingException; 15 | 16 | /** 17 | * Created by Linhh on 16/11/30. 18 | */ 19 | 20 | public class DilutionsUtil { 21 | 22 | public static String ENCODING = "UTF-8"; 23 | 24 | public static Object getParams(String type){ 25 | if("boolean".equals(type)){ 26 | return false; 27 | } 28 | if("char".equals(type)){ 29 | return null; 30 | } 31 | if("short".equals(type)){ 32 | return 0; 33 | } 34 | if("int".equals(type)){ 35 | return 0; 36 | } 37 | if("float".equals(type)){ 38 | return 0f; 39 | } 40 | if("double".equals(type)){ 41 | return 0f; 42 | } 43 | if("long".equals(type)){ 44 | return 0; 45 | } 46 | if("byte".equals(type)){ 47 | return null; 48 | } 49 | return null; 50 | } 51 | 52 | public static Class getParamsClass(String type) throws Exception{ 53 | if("boolean".equals(type)){ 54 | return boolean.class; 55 | } 56 | if("char".equals(type)){ 57 | return char.class; 58 | } 59 | if("short".equals(type)){ 60 | return short.class; 61 | } 62 | if("int".equals(type)){ 63 | return int.class; 64 | } 65 | if("float".equals(type)){ 66 | return float.class; 67 | } 68 | if("double".equals(type)){ 69 | return double.class; 70 | } 71 | if("long".equals(type)){ 72 | return long.class; 73 | } 74 | return Class.forName(type); 75 | } 76 | 77 | public static Object formatString(Object obj){ 78 | if(obj == null){ 79 | return ""; 80 | } 81 | if(obj instanceof String){ 82 | return String.valueOf(obj); 83 | } 84 | return obj; 85 | } 86 | 87 | /** 88 | * BASE64 解码,URL_SAFE 89 | * 90 | * @param input 91 | * @return 92 | */ 93 | //TODO 94 | @TargetApi(Build.VERSION_CODES.FROYO) 95 | public static String base64UrlDecode(String input) { 96 | input = input.replace("/", "_").replace("+", "-").replace("=", ""); 97 | String result = null; 98 | byte[] b = Base64.decode(input, Base64.URL_SAFE); 99 | try { 100 | result = new String(b, ENCODING); 101 | } catch (UnsupportedEncodingException e) { 102 | e.printStackTrace(); 103 | } 104 | return result; 105 | } 106 | 107 | public static boolean isNull(String str) { 108 | try { 109 | if (str == null) { 110 | return true; 111 | } else if (str != null) { 112 | if (str.equals("") || str.equals("null") || str.equals("[]")) { 113 | return true; 114 | } else return str.trim().equals("") || str.trim().equals("null"); 115 | } else { 116 | return false; 117 | } 118 | } catch (Exception ex) { 119 | ex.printStackTrace(); 120 | } 121 | return true; 122 | 123 | } 124 | 125 | public static boolean isEqual(String src, String dest) { 126 | try { 127 | if (src == null) 128 | src = ""; 129 | if (dest == null) 130 | dest = ""; 131 | return src.equals(dest); 132 | } catch (Exception ex) { 133 | ex.printStackTrace(); 134 | } 135 | return false; 136 | } 137 | 138 | /** 139 | * 内部放path需要的数据 140 | */ 141 | public static final String PARAMS_KEY = "params"; 142 | 143 | /* 144 | public static String ID = "id"; 145 | public static String URL = "url"; 146 | public static String COMMUNITY_CATEGORY_TAB = "community_category_tab";*/ 147 | 148 | 149 | public static boolean isFromUri(Intent intent) { 150 | if (intent == null) { 151 | return false; 152 | } 153 | return isFromUri(intent.getExtras()); 154 | } 155 | 156 | public static boolean isFromUri(Bundle bundle) { 157 | if (bundle == null) { 158 | return false; 159 | } 160 | String json = bundle.getString(DilutionsInstrument.URI_CALL_PARAM); 161 | if (isNull(json)) { 162 | return false; 163 | } 164 | return true; 165 | } 166 | 167 | public static String getValue(String name, Bundle bundle) { 168 | try { 169 | String json = bundle.getString(DilutionsInstrument.URI_CALL_PARAM); 170 | if (!isNull(json)) { 171 | JSONObject jsonObject = new JSONObject(json); 172 | String jsonValue = jsonObject.getString("params"); 173 | if (!isNull(jsonValue)) { 174 | JSONObject job = new JSONObject(jsonValue); 175 | Object value = job.get(name); 176 | if (value != null) { 177 | if (value instanceof Integer) { 178 | return (Integer) value + ""; 179 | } 180 | return value.toString(); 181 | } 182 | } 183 | } 184 | } catch (Exception e) { 185 | e.printStackTrace(); 186 | } 187 | return ""; 188 | } 189 | 190 | private static String getValue(String name, String defValue, Bundle bundle) { 191 | try { 192 | String json = bundle.getString(DilutionsInstrument.URI_CALL_PARAM); 193 | if (!isNull(json)) { 194 | JSONObject jsonObject = new JSONObject(json); 195 | String jsonValue = jsonObject.optString(PARAMS_KEY); 196 | if (!isNull(jsonValue)) { 197 | JSONObject job = new JSONObject(jsonValue); 198 | Object value = job.opt(name); 199 | if (value != null) { 200 | if (value instanceof Integer) { 201 | return (Integer) value + ""; 202 | } 203 | return value.toString(); 204 | } 205 | } 206 | } 207 | } catch (Exception e) { 208 | e.printStackTrace(); 209 | } 210 | return defValue; 211 | } 212 | 213 | public static String getParamByBundle(Bundle bundle) { 214 | try { 215 | String json = bundle.getString(DilutionsInstrument.URI_CALL_PARAM); 216 | if (!isNull(json)) { 217 | JSONObject jsonObject = new JSONObject(json); 218 | return jsonObject.getString(PARAMS_KEY); 219 | } 220 | } catch (Exception e) { 221 | e.printStackTrace(); 222 | } 223 | return ""; 224 | } 225 | /** 226 | * 获取Intent参数值 227 | * 228 | * @param name;参数名字;UriParam 提供了很多通用的参数,可以直接用; 229 | * @param intent 230 | * @return 231 | */ 232 | public static String getIntentParam(String name, Intent intent) { 233 | return getValue(name, "", intent.getExtras()); 234 | } 235 | 236 | public static com.alibaba.fastjson.JSONObject getUriParamsWithString(String uri_s) throws Exception { 237 | Uri uri = Uri.parse(uri_s); 238 | String params = uri.getQueryParameter("params"); 239 | params = DilutionsUtil.base64UrlDecode(params); 240 | com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(params); 241 | return jsonObject; 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /Dilutions/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Dilutions 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dilutions 2 | 3 | Dilutions是一个专门用于模块间数据协议通信的解耦协议框架,提供高性能数据分析和通信功能,解耦多项目多模块间的数据通信,简化代码逻辑成本。 4 | 5 | 通过一段URI字符串就能实现所有操作。 6 | 7 | 这个框架已经在 美柚 稳定 ,2016 年就开始使用,美柚总用户突破1亿,日活接近千万,Dilutions框架经过亿万用户的测试,代码的稳定性是可以放心的。有需求或者bug可以提issues,我会尽快回复。 8 | 9 | ![](http://sc.seeyouyima.com/shopGuide/data/59647e039f684_1920_576.png?imageView2/2/w/800/h/600) 10 | 11 | # 跨模块UI跳转 12 | 13 | 通过Dilutions实现跨模块间的UI跳转。 14 | 15 | ## 基本UI跳转 16 | 17 | 假设此时需要从模块1中的界面A跳转到模块2中的界面B,并且携带一些数据,由于模块1和模块2之间互不依赖,想要跨模块打开某个界面是比较困难的。 18 | 19 | Dilutions提供了跨模块间的UI跳转能力,通过定义一串共同的URI协议即可实现界面A到界面B的跳转。 20 | 21 | 假设我们约定这串跳转协议URI为: 22 | 23 | ```java 24 | String uri = "dilutions:///ui/atob" 25 | ``` 26 | 27 | 那么,这时只要在界面B中加上注解: 28 | 29 | ```java 30 | @ActivityProtocol("/ui/atob") 31 | public class ActivityB extends AppCompatActivity { 32 | @Override 33 | protected void onCreate(Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | } 36 | } 37 | ``` 38 | 39 | 界面A调用如下语句即可实现UI跳转: 40 | 41 | ```java 42 | Dilutions.create().formatProtocolService(uri); 43 | ``` 44 | 45 | ## 携带数据 46 | 47 | 如果这时候界面B需要接收一些参数,那么界面A如何传递呢? 48 | 49 | 我们假设界面B需要的参数如下: 50 | 51 | ```java 52 | int user_id; 53 | String user_name; 54 | ``` 55 | 56 | 那么界面B只需要将界面代码改为: 57 | 58 | ```java 59 | @ActivityProtocol("/ui/atob") 60 | public class ActivityB extends AppCompatActivity { 61 | @ActivityProtocolExtra("user_id") 62 | int user_id; 63 | 64 | @ActivityProtocolExtra("user_name") 65 | String user_name; 66 | 67 | @Override 68 | protected void onCreate(Bundle savedInstanceState) { 69 | super.onCreate(savedInstanceState); 70 | 71 | Dilutions.create().register(this);//注意,一定要注册dilutions 72 | 73 | Log.i(user_id + user_name);//使用传递过来的数据 74 | } 75 | } 76 | ``` 77 | 78 | 界面A通过调用如下代码即可传递参数并且实现跳转: 79 | 80 | ```java 81 | String uri = "dilutions:///ui/atob" 82 | HashMap map = new HashMap<>(); 83 | map.put("user_id", 222); 84 | map.put("user_name", "二红"); 85 | Dilutions.create().formatProtocolService(uri, map, null); 86 | ``` 87 | 88 | ## 携带对象数据 89 | 90 | 有的时候,我们传递的不一定是基础类型,而是对象,Dilutions也可以帮你完成传递 91 | 92 | ```java 93 | @ActivityProtocol("/ui/atob") 94 | public class ActivityB extends AppCompatActivity { 95 | @ActivityProtocolExtra("test_object") 96 | TestObject test_object; 97 | } 98 | ``` 99 | 100 | 界面A通过调用如下代码即可传递参数并且实现跳转: 101 | 102 | ```java 103 | String uri = "dilutions:///ui/atob" 104 | HashMap map = new HashMap<>(); 105 | map.put("test_object", new TestObject); 106 | Dilutions.create().formatProtocolService(uri, map, null); 107 | ``` 108 | 109 | 而界面B中可以直接拿到那个对象进行使用,但是需要注意的是传递的对象必须序列化。 110 | 111 | ## 转场动画 112 | 113 | 有时候需要动画转场来跳转界面,Dilutions也支持Activity的动画转场 114 | 115 | 只需要在对应的Activity加上注解即可 116 | 117 | ```java 118 | @ActivityProtocol({"/test","/test2"}) 119 | @CustomAnimation(enter = R.anim.enter, exit = R.anim.exit) 120 | public class MainActivity extends AppCompatActivity { 121 | } 122 | ``` 123 | 124 | CustomAnimation注解中的enter表示进入Activity的动画,exit为退出 125 | 126 | # 跨模块方法调用 127 | 128 | 我们上面学会了跨模块的UI跳转,下面将学到如何通过Dilutions进行跨模块的方法调用。 129 | 130 | 假设模块1想调用模块2的一个方法,模块1和模块2不互相依赖,你该怎么做呢? 131 | 132 | 再比如现在有方法A和方法B,想通过服务器决定来调用哪一个,怎么做比较好呢? 133 | 134 | Dilutions帮你解决了这个问题,使用方式和UI跳转差不多,你只需要URI协议字符串即可。 135 | 136 | ## 基础的跨模块调用方法 137 | 138 | 假设模块2中存在一个原生方法,这个方法之前是被模块2内的其他类直接使用的,现在需要支持跨模块特性。 139 | 140 | 首先模块2的方法需要加上注解: 141 | 142 | ```java 143 | @MethodProtocol("/method") 144 | public void method(){ 145 | Log.d("test","method had being called."); 146 | } 147 | ``` 148 | 149 | 这个方法可以在任何一个类中,任意地方,只需要注解。 150 | 151 | 接下来,你应该从UI跳转方法中学到了如何识别协议URI,没错,这个方法中的"/method"就是协议,因此协议应该长这样: 152 | 153 | ```java 154 | String uri = "dilutions:///method"; 155 | ``` 156 | 157 | 那么调用方依然是 158 | 159 | ```java 160 | Dilutions.create().formatProtocolService(uri); 161 | ``` 162 | 163 | 这样就完成了跨模块的方法调用。 164 | 165 | 所以你可以看到入口是不变的,一个方法可以通过URI协议的不同,正确的调用实现方。 166 | 167 | ## 携带参数 168 | 169 | 那么这时候你肯定想到了,我的方法肯定不可能都是无参啊,Dilutions可以支持带参调用吗? 170 | 171 | 答案是肯定的,仍然是通过注解。 172 | 173 | 我们假设有参方法method2如下: 174 | 175 | ```java 176 | public void method2(String username, int userid, boolean open){ 177 | Log.d("test","method had being called." + username + userid); 178 | } 179 | ``` 180 | 181 | 那么需要添加注解,改造成如下代码: 182 | 183 | ```java 184 | @MethodProtocol("/method2") 185 | public void method2(@MethodParam("username")String username, @MethodParam("userid")int userid, @MethodParam("open")boolean open){ 186 | Log.d("test","method had being called." + username + userid); 187 | } 188 | ``` 189 | 190 | 调用方只需要跟带数据跳转UI的操作方式一致就可以: 191 | 192 | ```java 193 | String uri = "dilutions:///method2" 194 | HashMap map = new HashMap<>(); 195 | map.put("user_id", 222); 196 | map.put("user_name", "二红"); 197 | map.put("open", true); 198 | Dilutions.create().formatProtocolService(uri, map, null); 199 | ``` 200 | 201 | 如果传递的数据不存在,比如没有传递open这个数据,那么对应的实现方法仍然会被执行,但是对应的入参会以默认值传入。 202 | 203 | ## 携带对象数据 204 | 205 | 跟跳转UI一样,Dilutions也可以携带对象数据跨模块调用方法。 206 | 207 | ```java 208 | @MethodProtocol("/method2") 209 | public void method2(@MethodParam("username")TestObject username){ 210 | Log.d("test","method had being called."); 211 | } 212 | ``` 213 | 214 | ## 方法实现方相关 215 | 216 | Dilutions对实现方的方法会进行自动映射,实现方不一定需要全部将入参标注参数,并且对注解顺序没有任何要求,比如: 217 | 218 | ```java 219 | @MethodProtocol("/method2") 220 | public void method2(@MethodParam("username")String username, int userid, @MethodParam("open")boolean open){ 221 | Log.d("test","method had being called." + username + userid); 222 | } 223 | ``` 224 | 225 | ## 方法返回值 226 | 227 | 那么你肯定还会提到,有的方法还有返回值,那么怎么办呢? 228 | 229 | Dilutions同样解决了这个问题。 230 | 231 | 将方法method2改为: 232 | 233 | ```java 234 | @MethodProtocol("/method2") 235 | public int method2(@MethodParam("username")String username, int userid, @MethodParam("open")boolean open){ 236 | Log.d("test","method had being called." + username + userid); 237 | return 0; 238 | } 239 | ``` 240 | 241 | 调用方改为 242 | 243 | ```java 244 | Dilutions.create().formatProtocolServiceWithCallback(uri,new DilutionsCallBack(){ 245 | public void onDilutions(DilutionsData data){ 246 | Object result = data.getResult(); 247 | //result即为方法调用返回值结果 248 | } 249 | }); 250 | ``` 251 | 252 | ## URI协议 253 | 254 | 在Dilutions中,我们知道所有的跨模块操作都是基于协议,因此,我们通过一串URI字符串即可实现跨模块的数据交互。 255 | 256 | 这个URI协议可以是从服务器下发的,也可以是客户端直接写好的,通过这个方式可以实现动态的方法调用和界面跳转。 257 | 258 | 在Dilutions中,协议的格式如下: 259 | 260 | ```xml 261 | dilutions:///circles/group?params=e2dyb3VwSUQ6Myx0ZXN0OiLmnpflro/lvJgifQ== 262 | ``` 263 | 264 | 其中dilutions:// 是协议头,这个是可以通过Dilutions自定义的,你可以给不同的app、业务设置不同的协议头,用来区分。 265 | 266 | 其中/circles/group这种,你已经知道了,他就是主要协议path,只有实现方实现了才会响应。 267 | 268 | 后面的params其实是固定样式,params=后面跟的是协议的数据参数,这个数据参数是base64过的json。 269 | 270 | 所以如果要实现动态跳转或者动态方法调用,服务器下发协议字符串需要采用这个逻辑构造。 271 | 272 | 在客户端中,Dilutions提供了一系列的工具类来帮助使用者生成,正常来说,我们只需要使用Dilutions.formatService相关方法即可,但是需求总是会变的,所以接下来会展示如何生成一个Dilutions的URI协议。 273 | 274 | ### 客户端生成URI协议 275 | 276 | ```java 277 | String uri = DilutionsUriBuilder.buildUri("dilutions://", "/testmap","{ \"path\":\"bi_information\", \"tt\" : {\"action\":1,\"floor\":2}}"); 278 | Dilutions.create().formatProtocolService(uri); 279 | ``` 280 | 281 | 以上代码片段是生成生成一个URI协议,然后再执行它。 282 | 283 | 你可以通过DilutionsUriBuilder这个类进行协议的生成和解析操作。 284 | 285 | ### 拦截协议 286 | 287 | 有的时候你可能需要拦截部分协议,在它们执行前进行额外的操作,那么拦截器是你的不二之选。 288 | 289 | ```java 290 | Dilutions.create().formatProtocolServiceWithInterceptor(uri, new DilutionsInterceptor(){ 291 | public boolean interceptor(DilutionsData data){ 292 | return false; 293 | } 294 | }) 295 | ``` 296 | 297 | 在拦截器的DilutionsData回调对象中存在很多获得协议信息的方法,比如执行的intent等,你可以对其进行修改,你甚至可以在里面重新定向到另一个协议实现,通过更改boolean返回值来决定(true=拦截,不继续执行原本的协议,false=继续执行)。 298 | 299 | ### 添加协议头 300 | 301 | 你可以通过动态添加协议头来决定你当前应用需要支持哪些协议。 302 | 303 | ```java 304 | Dilutions.create().getAppMap().add("dilutions2"); 305 | ``` 306 | 307 | ## 代理跳转UI 308 | 309 | 上面已经介绍过使用URI协议进行跳转UI,但实际上在Dilutions中,你还可以通过动态代理的方式进行跳转。 310 | 311 | 首先需要编写代理接口 312 | 313 | ```java 314 | public interface DebugService { 315 | 316 | @ProtocolPath("/test") 317 | void renderPage(@ExtraParam("test") String test, @ExtraParam("id") Object obj); 318 | } 319 | ``` 320 | 321 | 其中ProtocolPath内的是协议的path,方法名随意,ExtraParam注解对应的是参数名,后面跟类型。 322 | 323 | 编写完代理接口后,通过调用代理接口即可实现协议跳转执行。 324 | 325 | ```java 326 | Dilutions.create().formatProtocolService(DebugService.class).renderPage(参数); 327 | ``` 328 | 329 | PS:当前版本动态代理只能跳转UI,后续会实现跳转方法实现。 330 | 331 | ## 获取协议数据 332 | 333 | ### 注解获取 334 | 335 | 当你发起了一个协议打开一个UI的时候,你需要获得传递过来的协议数据,通过Dilutions注解可以在Activity或者Fragment中获得协议数据。 336 | 337 | 在Activity中: 338 | 339 | ```java 340 | /** 341 | * 读取test参数 342 | */ 343 | @ActivityProtocolExtra("test") 344 | TestObj st; 345 | 346 | /** 347 | * 读取query参数 348 | */ 349 | @ActivityProtocolExtra("query") 350 | int query; 351 | 352 | @ActivityProtocolExtra("groupID") 353 | int groupID; 354 | 355 | ``` 356 | 357 | 358 | 在Fragment中: 359 | 360 | ```java 361 | /** 362 | * 读取test参数 363 | */ 364 | @FragmentArg("test") 365 | TestObj st; 366 | 367 | /** 368 | * 读取query参数 369 | */ 370 | @FragmentArg("query") 371 | int query; 372 | 373 | @FragmentArg("groupID") 374 | int groupID; 375 | 376 | ``` 377 | 378 | 379 | 最后需要在对应的Activity或者Fragment的onCreate()方法中注册 380 | 381 | ```java 382 | Dilutions.create().register(this); 383 | ``` 384 | 385 | 386 | 注册完毕后,这些数据参数就可以使用了。 387 | 388 | PS:Dilutions直接任意数据对象传递。 389 | 390 | ### 原始获取 391 | 392 | 你可以不通过注解方式获取,你可以通过getIntent来获取注解,比如上述的数据通过下面的方式也可以获取到: 393 | 394 | ```java 395 | int query = getIntent().getIntExtra("query",0); 396 | ``` 397 | 398 | ### 额外参数获取 399 | 400 | 有时候你可能还想获得传递过来的完整协议,或者其他信息来处理一些业务需求,Dilutions定义了一些参数名,你可以通过注解方式也可以通过原始方式获得对应的数据。 401 | 402 | ```java 403 | class DilutionsInstrument{ 404 | //协议目标class类 405 | public static final String URI_CALL_CLASS = "uri-call-clazz"; 406 | //协议的path 407 | public static final String URI_CALL_PATH = "uri-call-path"; 408 | //协议的参数 409 | public static final String URI_CALL_PARAM = "uri-call-param"; 410 | //完整协议 411 | public static final String URI_CALL_ALL = "uri-call-all"; 412 | //如何跳转的,是代理还是协议 413 | public static final String URI_FROM = "uri-from"; 414 | } 415 | ``` 416 | 417 | ## 初始化 418 | 419 | Dilutions需要初始化才能够被使用,只需要一次即可。 420 | 421 | ```java 422 | Dilutions.init(Context); 423 | ``` 424 | 425 | ## gradle 426 | 427 | 当前最新版本1.0.8 428 | 429 | 430 | 在主工程最外层配置gradle :classpath 'linhonghong.lib:dilutions-compiler:1.0.6' 431 | 432 | ```groovy 433 | buildscript { 434 | repositories { 435 | jcenter() 436 | } 437 | dependencies { 438 | classpath 'com.android.tools.build:gradle:2.2.0' 439 | //添加这个 440 | classpath 'linhonghong.lib:dilutions-compiler:1.0.8' 441 | } 442 | } 443 | ``` 444 | 445 | 在需要dilutions的地方添加: 446 | 447 | ```groovy 448 | compile 'linhonghong.lib:dilutions:1.0.8' 449 | ``` 450 | 451 | Dilutions依赖阿里巴巴fastjson的json解析,因此需要在你的工程中依赖fastjson 452 | 453 | ```groovy 454 | compile 'com.alibaba:fastjson:1.1.68.android' 455 | ``` 456 | 457 | 主工程apply插件 458 | 459 | ```groovy 460 | apply plugin: 'dilutions' 461 | ``` 462 | 463 | Dilutions在Gradle2.x以及以上版本测试通过。 464 | 465 | ## 混淆 466 | 467 | ```xml 468 | -keep public class com.linhonghong.dilutions.inject.support.DilutionsInjectUIMetas 469 | -keep public class com.linhonghong.dilutions.inject.support.DilutionsInjectMeta 470 | ``` 471 | 472 | ## Developed By 473 | 474 | * Linhonghong - 475 | 476 | ## License 477 | Copyright 2016 LinHongHong 478 | 479 | Licensed under the Apache License, Version 2.0 (the "License"); 480 | you may not use this file except in compliance with the License. 481 | You may obtain a copy of the License at 482 | 483 | http://www.apache.org/licenses/LICENSE-2.0 484 | 485 | Unless required by applicable law or agreed to in writing, software 486 | distributed under the License is distributed on an "AS IS" BASIS, 487 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 488 | See the License for the specific language governing permissions and 489 | limitations under the License. 490 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'dilutions' 3 | 4 | android { 5 | compileSdkVersion 25 6 | buildToolsVersion '26.0.2' 7 | defaultConfig { 8 | applicationId "com.linhonghong.demo.dilutions" 9 | minSdkVersion 14 10 | targetSdkVersion 25 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:25.3.1' 25 | compile 'linhonghong.lib:dilutions:1.0.9' 26 | compile 'com.alibaba:fastjson:1.1.68.android' 27 | // compile project (":Dilutions") 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/Linhh/Develop/Android/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/assets/uiInterpreter.conf: -------------------------------------------------------------------------------- 1 | DILUTIONS.SCHEME.IN='dilutions.test' -------------------------------------------------------------------------------- /app/src/main/java/com/linhonghong/demo/dilutions/Application.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.demo.dilutions; 2 | 3 | import com.linhonghong.dilutions.Dilutions; 4 | 5 | public class Application extends android.app.Application{ 6 | @Override 7 | public void onCreate() { 8 | super.onCreate(); 9 | //初始化 10 | Dilutions.init(this); 11 | //添加协议头 12 | Dilutions.create().addScheme("dilutions2"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/linhonghong/demo/dilutions/DebugService.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.demo.dilutions; 2 | 3 | import com.linhonghong.dilutions.annotations.ExtraParam; 4 | import com.linhonghong.dilutions.annotations.ProtocolPath; 5 | 6 | /** 7 | * Created by Linhh on 17/3/7. 8 | */ 9 | 10 | public interface DebugService { 11 | 12 | @ProtocolPath("/test") 13 | void renderPage(@ExtraParam("test") String test, @ExtraParam("id") Object obj); 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/linhonghong/demo/dilutions/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.demo.dilutions; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | import android.view.View; 7 | 8 | import com.linhonghong.dilutions.Dilutions; 9 | import com.linhonghong.dilutions.annotations.ActivityProtocol; 10 | import com.linhonghong.dilutions.annotations.ActivityProtocolExtra; 11 | import com.linhonghong.dilutions.annotations.CustomAnimation; 12 | import com.linhonghong.dilutions.utils.DilutionsUriBuilder; 13 | 14 | import java.lang.reflect.*; 15 | import java.util.HashMap; 16 | 17 | /** 18 | * 演示UI协议跳转 19 | * 表示该Activity支持"/test","/test2"这两个协议 20 | */ 21 | @ActivityProtocol({"/test","/test2"}) 22 | @CustomAnimation(enter = R.anim.enter, exit = R.anim.exit) 23 | public class MainActivity extends AppCompatActivity { 24 | 25 | /** 26 | * 读取test参数 27 | */ 28 | @ActivityProtocolExtra("test") 29 | TestObj st; 30 | 31 | /** 32 | * 读取query参数 33 | */ 34 | @ActivityProtocolExtra("query") 35 | int query; 36 | 37 | @ActivityProtocolExtra("groupID") 38 | int groupID; 39 | 40 | // String test = "dilutions:///test?params=e2dyb3VwSUQ6Mn0="; 41 | String test = "dilutions:///circles/group?params=e2dyb3VwSUQ6Myx0ZXN0OiLmnpflro/lvJgifQ=="; 42 | //dilutions:///circles/group?params={groupID:0} 43 | 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | super.onCreate(savedInstanceState); 47 | Dilutions.init(this); 48 | //Activity注册 49 | Dilutions.create().register(this); 50 | 51 | //直接使用st参数 52 | // Log.i("test",st); 53 | setContentView(R.layout.activity_main); 54 | findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() { 55 | 56 | @Override 57 | public void onClick(View view) { 58 | //跳转方法 59 | if(test.equals("dilutions:///circles/group?params=e2dyb3VwSUQ6Myx0ZXN0OiLmnpflro/lvJgifQ==")){ 60 | test = "dilutions:///circles/group?params=e2dyb3VwSUQ6Mn0="; 61 | }else{ 62 | test = "dilutions:///circles/group?params=e2dyb3VwSUQ6Myx0ZXN0OiLmnpflro/lvJgifQ=="; 63 | } 64 | String s = DilutionsUriBuilder.buildUri("dilutions://", "/testmap","{ \"path\":\"bi_information\", \"tt\" : {\"action\":1,\"floor\":2}}"); 65 | Dilutions.create().formatProtocolService(s); 66 | // formatProtocolService(Test.class).renderPage(); 67 | // Dilutions.create().formatProtocolService(DebugService.class).renderPage(); 68 | // Dilutions.create().formatProtocolService(test); 69 | } 70 | }); 71 | findViewById(R.id.btn_test1).setOnClickListener(new View.OnClickListener() { 72 | @Override 73 | public void onClick(View view) { 74 | //协议跳转 75 | Bundle bundle = new Bundle(); 76 | // bundle.putString("test",new TestObj()); 77 | bundle.putString("name","linhonghong"); 78 | HashMap extraMap = new HashMap<>(); 79 | extraMap.put("mycallback", new View.OnClickListener() { 80 | @Override 81 | public void onClick(View v) { 82 | Log.d("testmethodobj", "回调完成"); 83 | } 84 | }); 85 | Log.d("testmethodobj", "协议开始"); 86 | Dilutions.create().formatProtocolServiceWithMap("dilutions:///obj?params=eyJ0dCI6eyJ0IjoieHh4c3NzIiwieCI6MTIyM319", null, extraMap); 87 | // Dilutions.create().formatProtocolService("dilutions","test",bundle) 88 | // Dilutions.create().setDilutionsPathInterceptor("/test", new DilutionsPathInterceptor() { 89 | // @Override 90 | // public boolean interceptor(DilutionsData data) { 91 | // return false; 92 | // } 93 | // }); 94 | HashMap map = new HashMap<>(); 95 | map.put("query", 222); 96 | TestObj r = new TestObj(); 97 | r.t = "tttt"; 98 | map.put("test", r); 99 | Dilutions.create().formatProtocolService("dilutions:///test?params=e2dyb3VwSUQ6Mn0=", map, null); 100 | // Dilutions.create().formatProtocolService("dilutions:///finish"); 101 | // String te = "dilutions:///doubles?params=eyJkb3VibGVzIjoyLjIyfQ=="; 102 | // Dilutions.create().formatProtocolServiceWithCallback(te, new DilutionsCallBack() { 103 | // @Override 104 | // public void onDilutions(DilutionsData data) { 105 | // Log.i("res", data.getResult().toString()); 106 | // } 107 | // }); 108 | } 109 | }); 110 | 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /app/src/main/java/com/linhonghong/demo/dilutions/Method.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.demo.dilutions; 2 | 3 | import android.os.Bundle; 4 | import android.util.Log; 5 | import android.view.View; 6 | 7 | import com.linhonghong.dilutions.DilutionsValue; 8 | import com.linhonghong.dilutions.annotations.MethodExtra; 9 | import com.linhonghong.dilutions.annotations.MethodParam; 10 | import com.linhonghong.dilutions.annotations.MethodProtocol; 11 | 12 | import java.util.HashMap; 13 | 14 | /** 15 | * 演示方法协议调用 16 | * Created by Linhh on 2017/6/26. 17 | */ 18 | 19 | public class Method { 20 | 21 | @MethodProtocol("/obj") 22 | public void obj(@MethodParam("tt") TestObj k, @MethodParam("mycallback") View.OnClickListener object){ 23 | Log.d("testmethodobj", "obj is called:" + object); 24 | object.onClick(null); 25 | } 26 | 27 | @MethodProtocol("/testmap") 28 | public void obj(@MethodParam("tt") HashMap k){ 29 | Log.d("testmethodobj", "obj is called."); 30 | } 31 | 32 | /** 33 | * 通过协议/finish可以直接跑到这里,无参的 34 | */ 35 | @MethodProtocol("/finish") 36 | public void finish(){ 37 | Log.d("finish","this Activity is finishing."); 38 | } 39 | 40 | @MethodProtocol("/doubles") 41 | public double dilutionsDouble(@MethodParam("doubles") double s){ 42 | Log.d("dilutionsDouble","dilutionsDouble is call." + s); 43 | return 10.3; 44 | } 45 | 46 | /** 47 | * 通过"/circles/group"协议 48 | * @param l 读取协议的groupID参数 49 | * @param b 50 | * @param a 51 | * @param t 读取协议的test参数 52 | */ 53 | @MethodProtocol("/circles/group") 54 | public void test1(@MethodParam("groupID") int l, 55 | Bundle b, 56 | int a, 57 | @MethodParam("test") String t){ 58 | Log.i("dilutions_test","n:" + l + ",t:" + t); 59 | } 60 | 61 | /** 62 | * 通过协议twapro2 63 | * @param a 64 | */ 65 | @MethodProtocol("twapro2") 66 | public void test1(int a){ 67 | Log.d("test","test1 had called."); 68 | } 69 | 70 | /** 71 | * 通过协议twapro3 72 | * @param t 参数tree 73 | */ 74 | @MethodProtocol("twapro3") 75 | public void test2(@MethodParam("tree") String t, @MethodExtra(DilutionsValue.DILUTIONS_METHOD_EXTRA) Object object){ 76 | Log.d("test","twapro3 had called."); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/linhonghong/demo/dilutions/Test.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.demo.dilutions; 2 | 3 | /** 4 | * Created by Linhh on 2017/7/19. 5 | */ 6 | 7 | public interface Test { 8 | @TestAno("tst") 9 | void renderPage(); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/linhonghong/demo/dilutions/TestAno.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.demo.dilutions; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.METHOD; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | @Documented 11 | @Target(METHOD) 12 | @Retention(RUNTIME) 13 | public @interface TestAno { 14 | String value() default ""; 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/linhonghong/demo/dilutions/TestObj.java: -------------------------------------------------------------------------------- 1 | package com.linhonghong.demo.dilutions; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by Linhh on 2017/7/6. 7 | */ 8 | 9 | public class TestObj implements Serializable{ 10 | public String t = "sssfs"; 11 | public int x = 2; 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/res/anim/enter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/anim/exit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |