【问题标题】:avoid doing onPostExecute()避免做 onPostExecute()
【发布时间】:2013-12-12 12:57:08
【问题描述】:

当使用 AsyncTask 并执行 doInBackground() 时,有时我会得到一个我不想继续到 onPostExecute() 的统计结果。 我尝试使用cancel(true);,但它仍然进入onPostExecute()

这是我的代码:

@Override
    protected LiveMatchDetails doInBackground(Void... params) {
        try {
            events = getLiveMatchEventsList(matchId, FetchPolicy.FROM_NETWORK);
        } catch (Exception e) {
            Log.e(TAG, "Error loading events", e);
            try {
                events = getLiveMatchEventsList(matchId, FetchPolicy.FROM_CACHE);
            } catch (Exception e1) {
                e1.printStackTrace();
                cancel(true);
                onProgressUpdate();
            }
        }
        return events;
    }

有没有办法阻止在 doInBAckground() 中调用 onPostExecute()?

【问题讨论】:

    标签: android android-asynctask


    【解决方案1】:

    没有没有办法避免 onPostExecute() 但你可以使用这样的结果部分跳过你的 onPostExecute() 代码:-

    拿一个标志或任何变量。

    int flag_response=0;
    @Override
        protected LiveMatchDetails doInBackground(Void... params) {
    
            try {
    
                events = getLiveMatchEventsList(matchId, FetchPolicy.FROM_NETWORK);
     flag_response=1;
            } catch (Exception e) {
                Log.e(TAG, "Error loading events", e);
                try {
                    events = getLiveMatchEventsList(matchId, FetchPolicy.FROM_CACHE);
                } catch (Exception e1) {
                    e1.printStackTrace();
                    cancel(true);
         flag_response=0;
                    onProgressUpdate();
                }
            }
            return events;
        }
    
    
    
     @Override
       protected void onPostExecute(String result) {
        if(flag_response==1)
        // execute your code
        else 
        //skip
        }
    

    【讨论】:

    • 那么,cancel(true) 是做什么的?
    • 调用“取消”向线程发送和中断信号。如果您的进程可以被中断,它将停止阻塞并继续执行。然后,您必须在 doInBackground() 中调用 isCancelled() 并在 isCancelled() 为真时从该方法返回。之后,onCanceled() 和 onPostExecute() 将被调用,线程将像 norma 一样自行死亡
    • 真诚地,我不同意您的回答:如果您可以简单地检查“事件”是否为空,为什么还要分配另一个变量?如果启动了异常,则捕获它并设置 events = null;然后在 onPostExecute() 中完成剩下的工作。
    • 如果你的事件没有在任何地方使用或者它只依赖于这个异步任务,你可以使用事件
    【解决方案2】:

    如果发生异常,则仅将 events = null; 放在 catch 块上并在 onPostExecute() 中执行以下操作:

    protected void onPostExecute(YourObject result) {
        if (result != null) {
            // do whatever you want
        }
    }
    

    顺便说一句,如果你看看这个link

    可以通过调用 cancel(boolean) 随时取消任务。 调用此方法将导致对 isCancelled() 的后续调用 返回真。调用此方法后,onCancelled(Object),改为 onPostExecute(Object) 将在之后调用 doInBackground(Object[]) 返回。确保任务被取消 尽快,你应该总是检查返回值 isCancelled() 定期从 doInBackground(Object[]),如果可能的话 (例如在循环内。)

    编辑

    如果抛出异常(在 doInBackground 方法发生的任何事情期间),您的代码 将直接转到 onPostExecute。如果你调用 cancel(true),那么你必须实现 onCancelled(Object) 并做任何你想做的事情。

    恕我直言,您必须在意外结果和取消任务之间有所作为:

    • 第一个由 catch 块快速管理,让您知道执行过程中发生了什么;
    • 第二个只有在您想打断您的任务时才有用,例如您按下后退按钮。

    这就是我使用 AsyncTask 的方式。

    【讨论】:

    • 从您附加的链接中我可以看到 cancel(true) 应该完成这项工作......我理解错了吗?如果没有,我会使用你的答案。
    • @roiberg 如果你使用 cancel(true),那么你还必须重写 onCancelled(Object) 方法。
    • 如果我将覆盖 onCancelled(Object) 而不是取消将导致它转到 onCancelled 而不是 onPostExecute()?
    • cancel() 不会完成这项工作。您可以调用 isCanceled() 它会返回您在 cancel() 中设置的内容
    【解决方案3】:

    只需在您的 AsyncTask 风格中添加一个私有 Exception 成员。

    private Exception exc = null;
    

    当您捕获异常时,将捕获的异常分配给您的私有 exc 值。

    catch (Exception e1) {
                    exc = e1;
                     // ... other handling code.
                }
    

    在 onPostExecute 检查 exc 是否为空。如果它为空(无异常),则执行您的代码。否则,什么也不做或发出错误消息。 编辑: 如果你想使用 cancel() 只需调用 if(isCancelled()) 来检查它是否被取消。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-25
      • 1970-01-01
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 2019-03-23
      • 1970-01-01
      相关资源
      最近更新 更多