This commit is contained in:
2021-09-22 10:02:44 +08:00
commit f298a018c6
729 changed files with 56782 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
package com.xiangxue.arouter_api;
import android.content.Context;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.xiangxue.arouter_api.test", appContext.getPackageName());
}
}

View File

@@ -0,0 +1,2 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xiangxue.arouter_api" />

View File

@@ -0,0 +1,23 @@
package com.xiangxue.arouter_api;
import java.util.Map;
/**
* Group分组的领头 带头大哥
*
*
* TODO
* * key: app
* * value: ARouterPath
*/
public interface ARouterGroup {
/**
* 例如order分组下有这些信息personal分组下有这些信息
* 例如:"order" --- ARouterPath的实现类 -->APT生成出来的 ARouter$$Path$$order
*
* @return key:"order/app/personal" value:系列的order组下面所有的path---class
*/
Map<String, Class<? extends ARouterPath>> getGroupMap();
}

View File

@@ -0,0 +1,27 @@
package com.xiangxue.arouter_api;
import com.xiangxue.arouter_annotation.bean.RouterBean;
import java.util.Map;
/**
* 其实就是 路由组 Group 对应的 ---- 详细Path加载数据接口 ARouterPath
* 例如order分组 对应 ---- 有那些类需要加载Order_MainActivity Order_MainActivity2 ...
*
*
* TODO
* key: /app/MainActivity1
* value: RouterBean(MainActivity1.class)
*
*/
public interface ARouterPath {
/**
* 例如order分组下有这些信息personal分组下有这些信息
*
* @return key:"/order/Order_MainActivity" 或 "/personal/Personal_MainActivity"
* value: RouterBean==Order_MainActivity.class 或 RouterBean=Personal_MainActivity.class
*/
Map<String, RouterBean> getPathMap();
}

View File

@@ -0,0 +1,70 @@
package com.xiangxue.arouter_api;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import java.io.Serializable;
/**
* 跳转时 ,用于参数的传递
*/
public class BundleManager {
// Intent传输 携带的值,保存到这里
private Bundle bundle = new Bundle();
// TODO 新增点
// 底层业务接口
private Call call;
Call getCall() {
return call;
}
void setCall(Call call) {
this.call = call;
}
public Bundle getBundle() {
return this.bundle;
}
// 对外界提供,可以携带参数的方法
public BundleManager withString(@NonNull String key, @Nullable String value) {
bundle.putString(key, value);
return this; // 链式调用效果 模仿开源框架
}
public BundleManager withBoolean(@NonNull String key, @Nullable boolean value) {
bundle.putBoolean(key, value);
return this;
}
public BundleManager withInt(@NonNull String key, @Nullable int value) {
bundle.putInt(key, value);
return this;
}
public BundleManager withSerializable(@NonNull String key, @Nullable Serializable object) {
bundle.putSerializable(key, object);
return this;
}
public BundleManager withBundle(Bundle bundle) {
this.bundle = bundle;
return this;
}
// Derry只写到了这里同学们可以自己增加 ...
// 直接完成跳转
public Object navigation(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return RouterManager.getInstance().navigation(context, this);
}
return null;
}
}

View File

@@ -0,0 +1,11 @@
package com.xiangxue.arouter_api;
/**
* 跨模块业务回调,空接口可集成拓展/实现
*
* 图片共享 组件 和 组件之间
* Bean共享 组件 和 组件之间
* ....
*/
public interface Call {
}

View File

@@ -0,0 +1,11 @@
package com.xiangxue.arouter_api;
public interface ParameterGet {
/**
* 目标对象.属性名 = getIntent().属性类型... 完成赋值操作
* @param targetParameter 目标对象例如MainActivity 中的那些属性
*/
void getParameter(Object targetParameter);
}

View File

@@ -0,0 +1,60 @@
package com.xiangxue.arouter_api;
import android.app.Activity;
import android.util.LruCache;
/**
* 参数的 加载管理器
* TODO 同学们:这是用于接收参数的
*
* 第一步:查找 Personal_MainActivity$$Parameter
* 第二步:使用 Personal_MainActivity$$Parameter this 给他
*/
public class ParameterManager {
private static ParameterManager instance;
// private boolean isCallback;
public static ParameterManager getInstance() {
if (instance == null) {
synchronized (ParameterManager.class) {
if (instance == null) {
instance = new ParameterManager();
}
}
}
return instance;
}
// LRU缓存 key=类名 value=参数加载接口
private LruCache<String, ParameterGet> cache;
private ParameterManager() {
cache = new LruCache<>(100);
}
// 为什么还要拼接,此次拼接 是为了寻找他
static final String FILE_SUFFIX_NAME = "$$Parameter"; // 为了这个效果Order_MainActivity + $$Parameter
// 使用者 只需要调用这一个方法,就可以进行参数的接收
public void loadParameter(Activity activity) { // 必须拿到 Personal_MainActivity
String className = activity.getClass().getName(); // className == Personal_MainActivity
ParameterGet parameterLoad = cache.get(className); // 先从缓存里面拿 如果有 如果没有
if (null == parameterLoad) { // 缓存里面没东东 提高性能
// 拼接 如Order_MainActivity + $$Parameter
// 类加载Order_MainActivity + $$Parameter
try {
// 类加载Personal_MainActivity + $$Parameter
Class<?> aClass = Class.forName(className + FILE_SUFFIX_NAME);
// 用接口parameterLoad = 接口的实现类Personal_MainActivity
parameterLoad = (ParameterGet) aClass.newInstance();
cache.put(className, parameterLoad); // 保存到缓存
} catch (Exception e) {
e.printStackTrace();
}
}
parameterLoad.getParameter(activity); // 最终的执行 会执行我们生成的类
}
}

View File

@@ -0,0 +1,162 @@
package com.xiangxue.arouter_api;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.util.LruCache;
import androidx.annotation.RequiresApi;
import com.xiangxue.arouter_annotation.bean.RouterBean;
/**
* 整个目标
* 第一步:查找 ARouter$$Group$$personal ---> ARouter$$Path$$personal
* 第二步:使用 ARouter$$Group$$personal ---> ARouter$$Path$$personal
*/
public class RouterManager {
private String group; // 路由的组名 apporderpersonal ...
private String path; // 路由的路径 例如:/order/Order_MainActivity
/**
* 上面定义的两个成员变量意义:
* 1.拿到ARouter$$Group$$personal 根据组名 拿到 ARouter$$Path$$personal
* 2.操作路径,通过路径 拿到 Personal_MainActivity.class就可以实现跳转了
*/
// 单例模式
private static RouterManager instance;
public static RouterManager getInstance() {
if (instance == null) {
synchronized (RouterManager.class) {
if (instance == null) {
instance = new RouterManager();
}
}
}
return instance;
}
// 提供性能 LRU缓存
private LruCache<String, ARouterGroup> groupLruCache;
private LruCache<String, ARouterPath> pathLruCache;
// 为了拼接,例如:ARouter$$Group$$personal
private final static String FILE_GROUP_NAME = "ARouter$$Group$$";
private RouterManager() {
groupLruCache = new LruCache<>(100);
pathLruCache = new LruCache<>(100);
}
/***
* @param path 例如:/order/Order_MainActivity
* * @return
*/
public BundleManager build(String path) {
if (TextUtils.isEmpty(path) || !path.startsWith("/")) {
throw new IllegalArgumentException("不按常理出牌 path乱搞的啊正确写法如 /order/Order_MainActivity");
}
// 同学可以自己增加
// ...
if (path.lastIndexOf("/") == 0) { // 只写了一个 /
throw new IllegalArgumentException("不按常理出牌 path乱搞的啊正确写法如 /order/Order_MainActivity");
}
// 截取组名 /order/Order_MainActivity finalGroup=order
String finalGroup = path.substring(1, path.indexOf("/", 1)); // finalGroup = order
if (TextUtils.isEmpty(finalGroup)) {
throw new IllegalArgumentException("不按常理出牌 path乱搞的啊正确写法如 /order/Order_MainActivity");
}
// 证明没有问题,没有抛出异常
this.path = path; // 最终的效果:如 /order/Order_MainActivity
this.group = finalGroup; // 例如orderpersonal
// TODO 走到这里后 grooup 和 path 没有任何问题 apporderpersonal /app/MainActivity
return new BundleManager(); // Builder设计模式 之前是写里面的, 现在写外面吧
}
// 真正的导航
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public Object navigation(Context context, BundleManager bundleManager) {
// 例如:寻找 ARouter$$Group$$personal 寻址 ARouter$$Group$$order ARouter$$Group$$app
String groupClassName = context.getPackageName() + "." + FILE_GROUP_NAME + group;
Log.e("derry >>>", "navigation: groupClassName=" + groupClassName);
try {
// TODO 第一步 读取路由组Group类文件
ARouterGroup loadGroup = groupLruCache.get(group);
if (null == loadGroup) { // 缓存里面没有东东
// 加载APT路由组Group类文件 例如ARouter$$Group$$order
Class<?> aClass = Class.forName(groupClassName);
// 初始化类文件
loadGroup = (ARouterGroup) aClass.newInstance();
// 保存到缓存
groupLruCache.put(group, loadGroup);
}
if (loadGroup.getGroupMap().isEmpty()) {
throw new RuntimeException("路由表Group报废了..."); // Group这个类 加载失败
}
// TODO 第二步 读取路由Path类文件
ARouterPath loadPath = pathLruCache.get(path);
if (null == loadPath) { // 缓存里面没有东东 Path
// 1.invoke loadGroup
// 2.Map<String, Class<? extends ARouterLoadPath>>
Class<? extends ARouterPath> clazz = loadGroup.getGroupMap().get(group);
// 3.从map里面获取 ARouter$$Path$$personal.class
loadPath = clazz.newInstance();
// 保存到缓存
pathLruCache.put(path, loadPath);
}
// TODO 第三步 跳转
if (loadPath != null) { // 健壮
if (loadPath.getPathMap().isEmpty()) { // pathMap.get("key") == null
throw new RuntimeException("路由表Path报废了...");
}
// 最后才执行操作
RouterBean routerBean = loadPath.getPathMap().get(path);
if (routerBean != null) {
switch (routerBean.getTypeEnum()) {
case ACTIVITY:
Intent intent = new Intent(context, routerBean.getMyClass()); // 例如getClazz == Order_MainActivity.class
intent.putExtras(bundleManager.getBundle()); // 携带参数
// context.startActivity(intent, bundleManager.getBundle()); // 大部分手机有问题,没有任何反应
context.startActivity(intent);
break;
case CALL:
// OrderAddressImpl.class OrderBean getOrderBean
Class<?> clazz = routerBean.getMyClass(); // OrderUserImpl BaseUser实体
Call call = (Call) clazz.newInstance();
bundleManager.setCall(call);
return bundleManager.getCall();
//同学们可以自己扩展 类型
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">ARouter_Api</string>
</resources>

View File

@@ -0,0 +1,17 @@
package com.xiangxue.arouter_api;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}