Giter Club home page Giter Club logo

hll-wp-therouter-android's Introduction

TheRouter: Android componentization solution

Hex.pm Language Wiki

Android | iOS | 中文官网 | 英文官网

A. Features

TheRouter core functions have four functionalities:

demo gif

B. Introduction

For more detailed documentation, please check the project wikiWiki

B1. Gradle configuration

module apt router plugin
version apt router plugin
// root build.gradle 
classpath 'cn.therouter:plugin:1.2.2'

// app module 
apply plugin: 'therouter'

// dependencies
kapt "cn.therouter:apt:1.2.2"
implementation "cn.therouter:router:1.2.2"

B2. initialization library

The library contains the automatic initialization function inside,link to: Single module automatic initialization; therefore, there's no need for any initialization code. However, it is recommended that you set the Debug environment according to your business settings to view log information.

@Override
protected void attachBaseContext(Context base) {
    TheRouter.setDebug(true or false);
    super.attachBaseContext(base);
}

B3. page parameter injection

Called in the onCreate() method of Activity or Fragment:
(It is recommended to do it directly in BaseActivity(BaseFragment))

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TheRouter.inject(this);
}

B4. page navigation

For the meaning of the annotation @Route, please check the documentation: Page Navigation

@Route(path = "http://therouter.com/home", action = "action://scheme.com",
        description = "second page", params = {"hello", "world"})
public class HomeActivity extends BaseActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TheRouter.build("Path")
            .withInt("intValue", 12345678)
            .withString("str_123_Value", "传中文字符串")
            .withBoolean("boolValue", true)
            .withLong("longValue", 123456789012345L)
            .withChar("charValue", 'c')
            .withDouble("double", 3.14159265358972)
            .withFloat("floatValue", 3.14159265358972F)
            .navigation();
    }
}

C. proguard rules configuration

# need add for Fragment page route
# -keep public class * extends android.app.Fragment
# -keep public class * extends androidx.fragment.app.Fragment
# -keep public class * extends android.support.v4.app.Fragment

-keep class androidx.annotation.Keep
-keep @androidx.annotation.Keep class * {*;}
-keepclassmembers class * {
    @androidx.annotation.Keep *;
}
-keepclasseswithmembers class * {
    @androidx.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
    @androidx.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
    @androidx.annotation.Keep <init>(...);
}
-keepclasseswithmembers class * {
    @com.therouter.router.Autowired <fields>;
}

D. Build and Debug

D1. project module description

TheRouter
  ├─app
  │   └──sample
  ├─business-a
  │   └──modular business demo
  ├─business-b
  │   └──modular business demo
  ├─business-base
  │   └──modular business demo
  │
  ├─apt
  │   └──Annotation processor tool code
  │
  ├─plugin
  │   └──Gradle plugin
  │
  └─router
      └──library code

D2. run Project

  1. Open local.properties and declare the modules you want to debug. For example, if you want the source code to debug the apt module, you can declare apt=true
  2. sync Gradle change

D3. plugin source code debugging

plugin debugging is special; you'll need to modify the module name to enable plugin debugging.

  1. Modify the plugin folder name to buildSrc (Case sensitive)
  2. Remove classpath reference in root build.gradle
  3. sync Gradle change

E. Change Log

link to Releases:Github Releases

F. Author

HUOLALA mobile technology team

G. LICENSE

TheRouter is licensed under the Apache License 2.0: LICENSE.

hll-wp-therouter-android's People

Contributors

jiarwang avatar kymjs avatar limuyang2 avatar linwoain avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hll-wp-therouter-android's Issues

使用 createFragment 方法创建 Fragment,release 版本会闪退。

使用 ViewPager2 承载 Fragment ,使用 TheRouter.build("app/fragment/mine").createFragment<Fragment>()创建 Fragment。debug 是正常的,release 下会闪退。具体日志:

java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.terek.mtv/cn.terek.mtv.ui.home.HomeActivity}: java.lang.RuntimeException: TheRouter::Navigator cn.terek.mtv.ui.home.fragment.MineFragment is not Fragment
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3431)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7664)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: java.lang.RuntimeException: TheRouter::Navigator cn.terek.mtv.ui.home.fragment.MineFragment is not Fragment
        at z6.d$a.l(Unknown Source:173)
        at z6.f$a.k(Unknown Source:14)
        at z6.d.a(Unknown Source:141)
        at cn.terek.mtv.ui.home.HomeActivity$b.a(Unknown Source:36)
        at f7.f.a(Unknown Source:20)
        at cn.terek.mtv.ui.home.HomeActivity.F(Unknown Source:12)
        at n2.a.onCreate(Unknown Source:251)
        at android.app.Activity.performCreate(Activity.java:7994)
        at android.app.Activity.performCreate(Activity.java:7978)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3404)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066at android.os.Handler.dispatchMessage(Handler.java:106at android.os.Looper.loop(Looper.java:223at android.app.ActivityThread.main(ActivityThread.java:7664at java.lang.reflect.Method.invoke(Native Methodat com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947

混淆已经添加

作者你好,提一个关于ActionInterceptor的问题

最近在使用TheRouter,功能非常强大,但在贴合业务场景时,我感觉addActionInterceptor的功能完全可以代替掉EventBus这种事件通知。
但是实际使用的话我觉得是否可以改进一下,比如我一个页面有多个事件通知,这些通知没有优先级,只是普通事件,处理业务逻辑。我要写多个TheRouter.addActionInterceptor(action,object:ActionInterceptor),页面销毁的时候我想removeAction,结果发现要把object:的对象单独抽出来才能进行remove;
但如果我每次写的时候我都把ActionInterceptor参数写成this,并实现handle方法的话,在handler中统一处理action事件,我感觉代码可能更集中一些,不会太分散,但现在handler方法中少一个action字段,我并不能知道这是哪个action来的,能否在handler中增加上action参数?

支持共享元素动画

ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(mActivity , view , getString(R.string.transitionName));
       
Aouter.build(path)
           .withOptionsCompat(options)
           .navigation(this);

不友好的功能吐槽

fun with(value: Bundle?): Navigator = withBundle(KEY_BUNDLE, value)设置的Bundle应该像ARouter那样可以从intent获取Bundle中的参数,而不是先获取Bundle再从此Bundle中获取参数,希望可以改进。

app工程在不clean情况下多次build会报Type com.xxx is defined multiple times

我在集成therouter app工程引入apply plugin: 'therouter'后,第一次构建项目能正常成功,但在不clean项目的情况下.修改模块内容后提交新的aar在次构建app项目时就会报Caused by: com.android.tools.r8.utils.b: Type com.xxxxx is defined multiple times .需要clean项目后在构建才能正常run起来.

用therouter源码复现方式:
拉取代码后再app模块引入 implementation 'com.airbnb.android:lottie:3.4.2' 构建运行.
然后将其版本号改为 implementation 'com.airbnb.android:lottie:3.7.2' 在不clean工程的情况下再次构建运行.即可得到报错信息

Cannot get property 'projectDir' on null object

每次正常运行项目后再次运行有几率报一下错误,一旦开始一次,后面必现,clean项目后才能正常跑,clean后再次运行依旧报错。

Caused by: java.lang.RuntimeException: java.lang.NullPointerException: Cannot get property 'projectDir' on null object at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:71) at com.android.build.gradle.internal.profile.AnalyticsResourceManager.recordBlockAtExecution(AnalyticsResourceManager.kt:227) at com.android.build.gradle.internal.profile.AnalyticsService.recordBlock(AnalyticsService.kt:161) at com.android.build.gradle.internal.pipeline.TransformTask.runTransform(TransformTask.java:168) at com.android.build.gradle.internal.pipeline.IncrementalTransformTask.transform(IncrementalTransformTask.java:133) at jdk.internal.reflect.GeneratedMethodAccessor1607.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:125) at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:47) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51) at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29) at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:236) at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29) at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47) at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68) at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:221) at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:204) at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:187) at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:165) at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:89) at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:40) at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:53) at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:50) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73) at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:50) at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:40) at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:68) at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:38) at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41) at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74) at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55) at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51) at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:29) at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.executeDelegateBroadcastingChanges(CaptureStateAfterExecutionStep.java:124) at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:80) at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:58) at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:48) at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:36) at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:181) at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$1(BuildCacheStep.java:71) at org.gradle.internal.Either$Right.fold(Either.java:175) at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:59) at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:69) at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:47) at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:36) at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:25) at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:36) at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:22) at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:110) at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$2(SkipUpToDateStep.java:56) at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:56) at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:38) at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:73) at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:44) at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37) at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27) at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:89) at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:50) at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:102) at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:57) at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:76) at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:50) at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNoEmptySources(SkipEmptyWorkStep.java:254) at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:91) at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:56) at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:32) at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:21) at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38) at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:43) at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:31) at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:40) at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:281) at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:40) at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30) at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37) at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27) at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:44) at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:33) at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:76) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:139) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:128) at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:77) at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46) at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:57) at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52) at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:69) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:322) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:309) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:302) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:288) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:462) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:379) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49) Caused by: java.lang.NullPointerException: Cannot get property 'projectDir' on null object at com.therouter.plugin.TheRouterTransform.theRouterTransform(TheRouterTransform.groovy:191) at jdk.internal.reflect.GeneratedMethodAccessor1608.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at com.therouter.plugin.TheRouterTransform.transform(TheRouterTransform.groovy:52) at com.android.build.api.transform.Transform.transform(Transform.java:324) at com.android.build.gradle.internal.pipeline.TransformTask$1.call(TransformTask.java:211) at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:69)

项目从 ARouter 迁移 TheRouter 时通过 Bundle 传递的参数不能正确获取 value

项目从 ARouter 迁移 TheRouter 时通过 Bundle 传递的参数不能正确获取 value

Example code

NavigatorTestActivity

Bundle bundle = new Bundle();
bundle.putInt("test_int_value", 1);

TheRouter.build(HomePathIndex.HOME)
    .with(bundle)
    .navigation();

NavigatorTargetActivity

Bundle bundle = getIntent().getExtras();
int intValueFromBundle = bundle.getInt("test_int_value", 0);

final TextView textView1 = findViewById(R.id.textview1);
textView1.setText("接收int值传递:integer2=" + intValueFromBundle);

Expected Result

integer2=1

Bundle 结构是下面这种

image

Actual Result:

integer2=0

image

Question

看起来与 ARouter 传递 Bundle 之后获取 Bundle 参数的方式不一致,不是能很平滑的迁移到 TheRouter.

之前旧项目使用 ARouter 时都是使用的

 ARouter.getInstance().build(path).with(bundle)
                .navigation(activity, requestCode)

传递参数,然后在对应页面使用 intent.extras?.getBoolean(KEY_WEB_VIEW_CLOSE_MODE, false) 这种方式获取参数,如果迁移到 TheRouter 之后必须使用 @Autowired 方式获取参数改动工作量会比较大。

我看了下源码:

fun with(value: Bundle?): Navigator = withBundle(KEY_BUNDLE, value)

我可以通过下面的方式获取传递的值

Bundle bundle = getIntent().getBundleExtra("therouter_bundle");
int intValueFromBundle = bundle.getInt("test_int_value", 0);

但是写法怪怪的,和以前用 ARouter 的写法也不兼容,是我写法有问题吗?或者有什么好的能够平滑迁移的建议?

An internal error occurred when clicking "测试导航功能" on the demo app

2023-02-06 15:12:55.838 16780-16780 TheRouter::RouterInject com.therouter.app                    D  class java.lang.Long do not have @ServiceProvider class. And constructor error::java.lang.Long.<init> []
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  java.lang.NoSuchMethodException: java.lang.Long.<init> []
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at java.lang.Class.getConstructor0(Class.java:2332)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at java.lang.Class.getDeclaredConstructor(Class.java:2170)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at com.therouter.inject.RouterInject.createDI(RouterInject.kt:101)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at com.therouter.inject.RouterInject.get(RouterInject.kt:54)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at com.therouter.TheRouter.get(TheRouter.kt:169)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at com.therouter.router.autowired.DefaultServiceParser.parse(DefaultServiceParser.kt:11)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at com.therouter.app.navigator.NavigatorTargetActivity__TheRouter__Autowired.autowiredInject(NavigatorTargetActivity__TheRouter__Autowired.java:43)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at a.TheRouterServiceProvideInjecter.autowiredInject(Unknown Source:19)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at com.therouter.TheRouter.inject(TheRouter.kt:193)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at com.therouter.app.navigator.NavigatorTargetActivity.onCreate(NavigatorTargetActivity.java:79)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.app.Activity.performCreate(Activity.java:8006)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.app.Activity.performCreate(Activity.java:7990)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3584)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3775)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2246)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.os.Handler.dispatchMessage(Handler.java:106)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.os.Looper.loop(Looper.java:233)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at android.app.ActivityThread.main(ActivityThread.java:8010)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at java.lang.reflect.Method.invoke(Native Method)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
2023-02-06 15:12:55.838 16780-16780 System.err              com.therouter.app                    W  	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)

RouteInject 方法中,"paramsClass" fallback的值在此处 对于Long类型并不适用。

if (!tClass.isInterface) {
      val paramsClass = if (params.isNotEmpty()) {
          val temp = arrayOfNulls<Class<*>?>(params.size)
          for (i in params.indices) {
              temp[i] = params[i]?.javaClass
          }
          temp
      } else arrayOfNulls<Class<*>?>(0)
      try {
          val constructor: Constructor<*> = tClass.getDeclaredConstructor(*paramsClass)
          if (!constructor.isAccessible) {
              constructor.isAccessible = true
          }
          t = constructor.newInstance(*params) as T
      } catch (e: Exception) {
          debugLog(tClass.toString() + " do not have @ServiceProvider class. And constructor error::" + e.message)
          e.printStackTrace()
      }
  } else {
      debugLog("$tClass is interface, but do not have @ServiceProvider")
  }

按文档集成后,调用跳转方法。没反应。

看了下生成的路由表是空的,不太明白是否有问题。
大佬能建个qq群吗?微信邀请二维码已经过期

18:38:27.111 D TheRouter init start!
18:38:27.111 D TheRouter.init() method do @flowtask before task
18:38:27.113 D TheRouter.init() method do @flowtask init
18:38:27.113 D TheRouter.init() method do @flowtask schedule
18:38:27.114 D TheRouter init finish!
18:38:27.114 D will be add route map from: initDefaultRouteMap()
18:38:27.114 D TheRouter auto init in Application
18:38:27.116 D will be add route map from assets: []
18:38:27.193 D begin navigate login_router_LoginActivity

Unable to get provider com.therouter.InnerTheRouterTrojan

版本:1.1.1-rc3
操作:正常编译运行,突然一次运行后报这个错。clean后问题依旧,已将com.therouter.InnerTheRouterTrojan添加至主Dex。
错误详情:
java.lang.RuntimeException: Unable to get provider com.therouter.InnerTheRouterTrojan: java.lang.ClassNotFoundException: Didn't find class "com.therouter.InnerTheRouterTrojan" on path: DexPathList[[zip file "/data/app/com.xxx.xxx-CMaxIG_Y01oTwcsNgQ3s0w==/base.apk"],nativeLibraryDirectories=[/data/app/com.xxx.xxx-CMaxIG_Y01oTwcsNgQ3s0w==/lib/arm64, /data/app/com.xxx.xxx-CMaxIG_Y01oTwcsNgQ3s0w==/base.apk!/lib/arm64-v8a, /system/lib64, /hw_product/lib64, /system/product/lib64]]
at android.app.ActivityThread.installProvider(ActivityThread.java:8173)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:7709)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7573)
at android.app.ActivityThread.access$2600(ActivityThread.java:260)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2435)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8668)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.therouter.InnerTheRouterTrojan" on path: DexPathList[[zip file "/data/app/com.xxx.xxx-CMaxIG_Y01oTwcsNgQ3s0w==/base.apk"],nativeLibraryDirectories=[/data/app/com.xxx.xxx-CMaxIG_Y01oTwcsNgQ3s0w==/lib/arm64, /data/app/com.xxx.xxx-CMaxIG_Y01oTwcsNgQ3s0w==/base.apk!/lib/arm64-v8a, /system/lib64, /hw_product/lib64, /system/product/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:209)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at android.app.AppComponentFactory.instantiateProvider(AppComponentFactory.java:147)
at androidx.core.app.CoreComponentFactory.instantiateProvider(CoreComponentFactory.java:67)
at android.app.ActivityThread.installProvider(ActivityThread.java:8157)

FlowTask中TheRouter_application_oncreate执行时机问题

我理解的dependsOn= TheRouter_Before_Initialization 在Application.onCreate之前
dependsOn = TheRouter_application_oncreate在SplashActivity.onCreate之前
dependsOn = TheRouter_activity_splash应该在SplashActivity.onCreate之后
但是事实TheRouter_application_oncreate的task一直在activity_splash之后,反而比TheRouter_activity_splash执行的时机更晚,
原因是TheRouter在init时异步启动TheRouter_application_oncreate的task
image
要想达到Application.onCreate之后SplashActivity.onCreate之前,只能在Application.onCreate中启动自定义任务
image

没有withParcelableArrayList

Bundle本身就支持,加上很简单,请问后面会支持吗?
现在虽然可以用Navigator的extras来搞,但还是链式调用就断了

请帮忙再把log里面的Trojan去掉。

@kymjs 不好意思,我们做海外的,欧盟的机构用扫描工具扫到"Trojan",请帮忙再修改一下,感谢

class InnerTheRouterContentProvider : ContentProvider() {
override fun onCreate(): Boolean {
applicationContext ?: let {
applicationContext = context
}
if (theRouterUseAutoInit) {
TheRouter.init(applicationContext)
debug("Trojan", "TheRouter auto init in Application")
}
return true
}
}

是否支持用户自定义拦截器

是否支持部分路由更精细化的权限控制,比如登录态、部分页面可进入。
所以是不是需要暴露给用户一个局部的自定义拦截器;
是否支持到模块内外路由可调用的的权限管理;

ServiceProvider apt生成的类有问题

public interface MyService {
    public void asd();
}
@ServiceProvider(returnType = MyService.class)
public class MyProvider implements MyService{
    @Override
    public void asd() {
        Log.d("asd", "hello");
    }
}

然后编译报错:TheRouterDemo2/demo2/build/generated/source/kapt/debug/a/ServiceProvider__TheRouter__1284289051.java:16: 错误: 需要<标识符>
if (com.example.demo2.provider.MyService.class.class.equals(clazz) && params.length == 1

apt生成的java文件被ide各种标红:

package a;

/**
 * Generated code, Don't modify!!!
 * Created by kymjs, and APT Version is 1.1.2.
 */
@androidx.annotation.Keep
public class ServiceProvider__TheRouter__1284289051 implements com.therouter.inject.Interceptor {

	public static final String TAG = "Created by kymjs, and APT Version is 1.1.2.";
	public static final String THEROUTER_APT_VERSION = "1.1.2";
	public static final String FLOW_TASK_JSON = "{}";

	public <T> T interception(Class<T> clazz, Object... params) {
		T obj = null;
		if (com.example.demo2.provider.MyService.class.class.equals(clazz) && params.length == 1
				&& params[0] instanceof {}) {
			// 加上编译期的类型校验,防止方法实际返回类型与注解声明返回类型不匹配
			com.example.demo2.provider.MyService.class returnType = new com.example.demo2.provider.MyProvider(({}) params[0]);
			obj = (T) returnType;
		} else {

        }
        return obj;
    }

	public static void addFlowTask(android.content.Context context, com.therouter.flow.Digraph digraph) {
	}
}

登录拦截

在使用路由拦截器时,需要区分那些页面需要登录,登录成功跳转对应的页面;
使用Navigator.addRouterReplaceInterceptor拦截器进行拦截判断
使用Route注解中的params参数进行判断是否需要登录
由于params是传递的参数,感觉不优雅,有其他方式判断那些页面需要登录那些页面不需要登录吗?
之前使用ARouter路由框架,Route注解有一个extras参数,没有跟其他业务有依赖,所以可以使用判断

父类@Autowared注解问题

该框架对单Activity模式项目不太友好。建议可以封装一下fragment相关路由。包括fragment栈管理。跳转传参返回等。

一但新增包导入重新编译,再次启动就崩溃,需要清除全部缓存重新编译才正常

Process: com.zhongcai.xiaofeng, PID: 7791
java.lang.NoClassDefFoundError: Failed resolution of: La/RouterMap__TheRouter__610679138;
at a.TheRouterServiceProvideInjecter.initDefaultRouteMap(Unknown Source)
at com.therouter.router.RouteMapKt.asyncInitRouteMap$lambda-4(RouteMap.kt:53)
at com.therouter.router.RouteMapKt.lambda$OiqKkQwCAH4GRN3KjIF5vkOx1G8(RouteMap.kt)
at com.therouter.router.-$$Lambda$RouteMapKt$OiqKkQwCAH4GRN3KjIF5vkOx1G8.run(lambda)
at com.therouter.Task.run(TheRouterThreadPool.kt:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.ClassNotFoundException: Didn't find class "a.RouterMap__TheRouter__610679138" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/com.zhongcai.xiaofeng-2/base.apk"],nativeLibraryDirectories=[/data/app/com.zhongcai.xiaofeng-2/lib/x86, /data/app/com.zhongcai.xiaofeng-2/base.apk!/lib/x86, /system/lib, /vendor/lib]]

出现java.lang.NoClassDefFoundError

09-23 15:47:51.013 26549 26549 E AndroidRuntime: java.lang.NoClassDefFoundError: Failed resolution of: La/ServiceProvider__TheRouter__1380433389; 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at a.TheRouterServiceProvideInjecter.addFlowTask(Unknown Source:10) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at com.therouter.TheRouter.init(TheRouter.kt:64) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at com.therouter.InnerTheRouterTrojan.onCreate(TheRouterTrojan.kt:26) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.content.ContentProvider.attachInfo(ContentProvider.java:2413) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.content.ContentProvider.attachInfo(ContentProvider.java:2383) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.app.ActivityThread.installProvider(ActivityThread.java:7771) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.app.ActivityThread.installContentProviders(ActivityThread.java:7288) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7028) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.app.ActivityThread.access$1800(ActivityThread.java:254) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2184) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:233) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.os.Looper.loop(Looper.java:344) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:8212) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584) 09-23 15:47:51.013 26549 26549 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)

项目结构
app module
接口module
实现a module
实现b module

module a、module b都是对接口的实现。app引用了接口module,当编译flavor a的时候,app引用的是实现a,当编译flavor b的时候,app引用的是实现b。a、b中都有各有一个ServiceProvider方法,现在发现不管哪种flavor,都会将module a、module b生成的类加到TheRouterServiceProvideInjecter中,但最终这个类并不会被打包进去,导致NoClassDefFoundError。

能否支持plugins引入id的方式

plugins {
id("com.android.application") version ("7.1.2") apply (false)
id("com.android.library") version ("7.1.2") apply (false)
id("org.jetbrains.kotlin.android") version ("1.7.10") apply (false)
}

引入插件后同步会提示警告信息

引入1.1.2版本,编译器执行同步操作会提示警告,日志如下

API 'android.registerTransform' is obsolete.
It will be removed in version 8.0 of the Android Gradle plugin.
The Transform API is removed to improve build performance. Projects that use the
Transform API force the Android Gradle plugin to use a less optimized flow for the
build that can result in large regressions in build times. It’s also difficult to
use the Transform API and combine it with other Gradle features; the replacement
APIs aim to make it easier to extend the build without introducing performance or
correctness issues.

There is no single replacement for the Transform API—there are new, targeted
APIs for each use case. All the replacement APIs are in the
`androidComponents {}` block.
For more information, see https://developer.android.com/studio/releases/gradle-plugin-api-updates#transform-api.
To determine what is calling android.registerTransform, use -Pandroid.debug.obsoleteApi=true on the command line to display more information.
Affected Modules: app

当我在gradle.properties添加android.debug.obsoleteApi=true后可以确定是引入插件id 'therouter'所引起的警告。
下面是警告信息和版本截图
image
image
image

能否将功能进行一下拆分?

TheRouter很好用,但是功能感觉略有复杂。来看看它的功能:

  1. 页面导航跳转能力
  2. 跨模块依赖注入能力
  3. 单模块自动初始化能力
  4. 动态化能力

作为一个Router,它的核心能力应该是1,最多再涉及一下2。而3和4,已经可以拆分出来作为一个独立的框架来使用了。

在我的两个项目中,A项目使用了router相关能力以及初始化能力,而2项目只需要它的初始化能力(因为我觉得蛮好用的),却要引入整个库及插件。

所以有没有考虑拆一下?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.