当 AsyncTask 中的 catch() 抛出错误时转到另一个活动

Posted

技术标签:

【中文标题】当 AsyncTask 中的 catch() 抛出错误时转到另一个活动【英文标题】:Go to another activity when error is thrown by catch() in AsyncTask 【发布时间】:2017-07-17 04:57:06 【问题描述】:

这是我的异步任务:

public class GetDataTask extends AsyncTask<Void, Void, JSONArray> 

        @Override
        protected void onPreExecute() 
            // [...]
        

        @Override
        protected void onPostExecute(JSONArray result) 

            int result_length = 0;

            try 
                result_length = result.length();
             catch (NullPointerException e) 
                e.printStackTrace();

                // Redirect the user back to the original activity
                Intent intent = new Intent(ResultActivity.this, MainActivity.class);
                startActivity(intent);
            


            for (int i = 0; i < result_length; i++) 
                // [...]
            
        

        @Override
        protected JSONArray doInBackground(Void... params) 
            // [...]
        

result 为空时,.length() 会抛出 NullPointerException。这就是为什么我想在发生这种情况时将 url 重定向回 MainActivity。

try 
    result_length = result.length();
 catch (NullPointerException e) 
    e.printStackTrace();

    // Redirect the user back to the original activity
    Intent intent = new Intent(ResultActivity.this, MainActivity.class);
    startActivity(intent);

问题是它不起作用。我得到e.printStackTrace(),但活动没有改变。这就像 Intent 不够“快”来改变活动,下面的代码 (for (int i = 0; i &lt; result_length; i++) ) 仍然在运行。 我能做些什么?我的解决方案错了吗?提前谢谢你。

【问题讨论】:

我认为异步任务是一个线程,这就是为什么 for 循环即使在遇到异常后也会执行。因此,您必须在收到错误后立即取消您的AsyncTask(即在catch 块中)。 【参考方案1】:

在 AsyncTask 构造函数中提供 Activity 引用。

private Activity activity;

public GetDataTask (Activity activity) 
   this.activity = activity;

那么你可以这样称呼它

activity.startActivity(new Intent(activity, MainActivity.class));

【讨论】:

【参考方案2】:

这就像 Intent 不够“快”来改变活动

当您通过startActivity() 启动活动时,您不会立即产生该操作。您只是请求框架为您启动指定的活动。这并不意味着在startActivity() 之后它下面的代码不会被调用。执行器将继续执行代码,直到作用域结束。如果你想在之后停止执行,你必须在startActivity() 之后立即return

【讨论】:

【参考方案3】:

就个人而言,catch (NullPointerException ) 总是错误的。加上if (variable == null) 可以说更快。

AsyncTask 应该只是return; 或停止,不一定开始任何事情。

另一个建议:确保doInBackground 返回一个空的JSONArray 而不是null

下面的代码 (for (int i = 0; i

当然,因为 for 循环不在 try 块内...

try 
    result_length = result.length();
 catch (NullPointerException e) 
    e.printStackTrace();

    // Redirect the user back to the original activity
    Intent intent = new Intent(ResultActivity.this, MainActivity.class);
    startActivity(intent);


// The result is still null here...

用更简单的空检查替换所有捕获,并且不要让循环进入。

@Override
protected void onPostExecute(JSONArray result) 

    int result_length = result == null ? 0 : result.length();

    for (int i = 0; i < result_length; i++) 
        // This loop won't run when the result is null... 
    

如果你真的想,然后检查if (result_length == 0),但同样,Activity 应该在结果完成时被回调,然后你可以开始一些其他的活动。

参考:How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

【讨论】:

以上是关于当 AsyncTask 中的 catch() 抛出错误时转到另一个活动的主要内容,如果未能解决你的问题,请参考以下文章

重新抛出 promise catch 中的错误

异常机制

c# throw抛出上一个异常

JAVA异常处理

抛出异常后不执行 Catch 块调试语句?

JAVA语言如何进行异常处理,关键字throws,throw,try,catch,finally分别代表啥意义在try块中抛出异常吗