使用Kotlin开发的时候,用ARouter传值跳转页面,进入页面出现第一次自动注入时正常,第二次自动注入无效的问题。
感觉莫名其妙,排查了好久,终于找到了问题,记录一下。
发起跳转是在MainActivity
ARouter.getInstance().build("/app/second")
.withInt("timeValue", 123)
.navigation(MainActivity@ this)
我们要跳转的目标页面是SecondActivity
@Route(path = "/app/second")
class SecondActivity : AppCompatActivity() {
@JvmField
@Autowired
var timeValue: Int? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
ARouter.getInstance().inject(this)
findViewById<TextView>(R.id.tv_info).text = "$timeValue"
}
}
然后,要跳转页面生成的类是SecondActivity$$ARouter$$Autowired
public class SecondActivity$$ARouter$$Autowired implements ISyringe {
private SerializationService serializationService;
@Override
public void inject(Object target) {
serializationService = ARouter.getInstance().navigation(SerializationService.class);
SecondActivity substitute = (SecondActivity)target;
substitute.timeValue = substitute.getIntent().getIntExtra("timeValue", substitute.timeValue);
}
}
由于getIntExtra传参用的是int
public int getIntExtra(String name, int defaultValue) {
return mExtras == null ? defaultValue :
mExtras.getInt(name, defaultValue);
}
所以,使用var timeValue: String? = null
没有赋值的情况下,会有报错 java.lang.NullPointerException:cannot unbox null value
导致AutowiredServiceImpl
中进入了catch的逻辑
public class AutowiredServiceImpl implements AutowiredService {
private LruCache<String, ISyringe> classCache;
private List<String> blackList;
@Override
public void init(Context context) {
classCache = new LruCache<>(66);
blackList = new ArrayList<>();
}
@Override
public void autowire(Object instance) {
String className = instance.getClass().getName();
try {
if (!blackList.contains(className)) {
ISyringe autowiredHelper = classCache.get(className);
if (null == autowiredHelper) { // No cache.
autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance();
}
autowiredHelper.inject(instance); //出现Crash
classCache.put(className, autowiredHelper);
}
} catch (Exception ex) {
//进入catch逻辑
blackList.add(className); // This instance need not autowired.
}
}
}
导致第二次进入页面的时候,获取到缓存的AutowiredServiceImpl,这个时候blackList是有存SecondActivity这个className的,导致不会再执行inject方法了。
所以,我们只需要给timeValue赋值一个初始值,就可以解决这个问题了。