ARouter — Calling startActivity() from outside of an Activity ...

ARouter 使用异常

    • 一、问题描述
    • 二、异常信息
    • 三、异常分析
    • 四、_ARouter代码分析
    • 五、解决方法

一、问题描述

异常:

Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

代码:

ARouter.getInstance()
	   .build("/main/activity/main")
	   .withFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)  //添加了一个Flag
	   .navigation();

二、异常信息

android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
	at android.app.ContextImpl.startActivity(ContextImpl.java:1381)
	at android.content.ContextWrapper.startActivity(ContextWrapper.java:334)
	at android.support.v4.content.ContextCompatJellybean.startActivity(ContextCompatJellybean.java:34)
	at android.support.v4.content.ContextCompat.startActivity(ContextCompat.java:151)
	at com.alibaba.android.arouter.launcher._ARouter$2.run(_ARouter.java:359)
	at android.os.Handler.handleCallback(Handler.java:815)
	at android.os.Handler.dispatchMessage(Handler.java:104)
	at android.os.Looper.loop(Looper.java:199)
	at android.app.ActivityThread.main(ActivityThread.java:5775)
	at java.lang.reflect.Method.invoke(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:372)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:975)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)

三、异常分析

错误原因:新启动的Activity没有在Activity栈里面,所以需要新增一个FLAG_ACTIVITY_NEW_TASK;
导致的原因:使用Application充当了context启动Activity;


四、_ARouter代码分析

// _ARouter类
final class _ARouter {
	// Applcation
    private static Context mContext;
    
    protected static synchronized boolean init(Application application) {
        mContext = application;
        LogisticsCenter.init(mContext, executor);
        logger.info(Consts.TAG, "ARouter init success!");
        hasInit = true;
        return true;
    }
    
private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
		// mContext = Applcation
        final Context currentContext = null == context ? mContext : context;

        switch (postcard.getType()) {
            case ACTIVITY:
                // Build intent
                final Intent intent = new Intent(currentContext, postcard.getDestination());
                intent.putExtras(postcard.getExtras());

                // Set flags.
                int flags = postcard.getFlags();//当设置flags时,flags!=-1
                if (-1 != flags) {
                    intent.setFlags(flags);
                } else if (!(currentContext instanceof Activity)) {    // Non activity, need less one flag.
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                }

                // Navigation in main looper.
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        if (requestCode > 0) {  // Need start for result
	                        // 如果启动需要返回值的Activity,则currentContext必须是Activity,否则强转会出现异常错误。
                            ActivityCompat.startActivityForResult((Activity) currentContext, intent, requestCode, postcard.getOptionsBundle());
                        } else {
	                        // 启动Activity时,currentContext如果是Applcation,且没有设置FLAG_ACTIVITY_NEW_TASK,就会出现上述的异常。
                            ActivityCompat.startActivity(currentContext, intent, postcard.getOptionsBundle());
                        }

                        if ((0 != postcard.getEnterAnim() || 0 != postcard.getExitAnim()) && currentContext instanceof Activity) {    // Old version.
                            ((Activity) currentContext).overridePendingTransition(postcard.getEnterAnim(), postcard.getExitAnim());
                        }

                        if (null != callback) { // Navigation over.
                            callback.onArrival(postcard);
                        }
                    }
                });

                break;
            case PROVIDER:
                return postcard.getProvider();
            case BOARDCAST:
            case CONTENT_PROVIDER:
            case FRAGMENT:
                Class fragmentMeta = postcard.getDestination();
                try {
                    Object instance = fragmentMeta.getConstructor().newInstance();
                    if (instance instanceof Fragment) {
                        ((Fragment) instance).setArguments(postcard.getExtras());
                    } else if (instance instanceof android.support.v4.app.Fragment) {
                        ((android.support.v4.app.Fragment) instance).setArguments(postcard.getExtras());
                    }

                    return instance;
                } catch (Exception ex) {
                    logger.error(Consts.TAG, "Fetch fragment instance error, " + TextUtils.formatStackTrace(ex.getStackTrace()));
                }
            case METHOD:
            case SERVICE:
            default:
                return null;
        }
}

五、解决方法

// 方案一
ARouter.getInstance()
	   .build("/main/activity/main")
	   .withFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)  //添加了一个Flag
	   .navigation(acitvityContext);//在此处传入当前的Activity,即可实现正常跳转。

// 方案二
ARouter.getInstance()
	   .build("/main/activity/main")
	   .withFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK)//新增一个Activity栈,不过会出现多个指定的Activity,因此不能解决需求问题,但可解决报错问题。
	   .navigation();

你可能感兴趣的:(开源框架源码分析)