【问题标题】:onPostExecute() of AsyncTask never get called in AndroidTestCaseAsyncTask 的 onPostExecute() 永远不会在 AndroidTestCase 中被调用
【发布时间】:2013-11-07 06:07:59
【问题描述】:

我正在为我的Android项目编写一个非常简单的单元测试用例,测试用例简单地执行一个AsyncTask,它在后台进行网络操作。我正在为我的测试用例扩展 AndroidTestCase 类:

public class MyTest extends AndroidTestCase{
  //use CountDownLatch to perform wait-notify behavior
  private CountDownLatch signal;
  @Override
  public void setUp() throws Exception{
     super.setUp();
     //I use CountDownLatch to perform wait-notify behaviour
     signal = new CountDownLatch(1); 
  }

  @Override
  public void runTest() throws Exception{
        String params = "some params";
        //MyAsyncTask does the networking tasks
        new MyAsyncTask().execute(params);

       //wait until MyAsyncTask is done
       try {
        signal.await();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    
  }

  private class MyAsyncTask extends AsyncTask<String, Void, String>{
        
    @Override
    protected String doInBackground(String... params) {
          //Do networking task e.g. access a remote database
     }
     
     @Override
    protected void onPostExecute(String result){
        super.onPostExecute(result);
            //this never get called when run this test case, why?
           Log.i("Debug","post execute");       
           signal.countDown();
    }
  }
}

正如你在上面看到的,我正在使用CountDownLatch 来执行等待通知行为。

MyAsicTask 启动后,我调用signal.await()等待MyAsyncTask 完成。

MyAsyncTaskonPostExecute()回调中,我调用signal.countDown()通知任务完成。

但是当我运行这个测试用例时,onPostExecute 永远不会被调用,为什么以及如何解决它?

========更新==========

runTest() 的最后一行添加Thread.sleep(30*1000) 后,我可以看到更多来自网络操作的日志。它证明teardown() 在我的网络操作完成之前被调用。我在 Android 测试框架 tearDown() 中什么也没做。自动调用它。

似乎我的 wait-notify 使用 CountDownLatch 不起作用...为什么?

【问题讨论】:

  • doInBackground 有异常吗?
  • doInBackground 可能出现问题,因此onPostExecute 没有接到电话..
  • @d3m0li5h3r 除非 doInbackground() 崩溃并取消异步任务,否则 onPostExecute() 不可能不会执行。
  • @Brontok.. 这正是我的意思.. 要么他在 doInBackground 中收到异常,要么任务已通过调用 cancel() 方法被取消。
  • 大家好,doInBackgroud()也不例外,tearDown()是在网络操作进行时调用的.....我使用CountDownLatch的目的是为了避免这种情况,但是它仍然会发生,为什么?

标签: java android multithreading android-intent android-asynctask


【解决方案1】:

因为我有同样的问题......这就是为我解决它的方法。 我没有让类扩展 AndroidTestCase,而是让它扩展 InstrumentationTestCase。

然后我像这样启动 asyncTask:

runTestOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
            startAsyncTask();
        }
    });

【讨论】:

    【解决方案2】:

    请确保您的 doInBackground 方法不是导致此问题的原因。试试这个示例任务。请分享日志结果。

    private class MyAsyncTask extends AsyncTask<String, Void, String> {
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.i("Debug", "onPreExecute");
        }
    
        @Override
        protected String doInBackground(String... params) {
            Log.i("Debug", "doInBackground");
            return "operation finished";
        }
    
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            Log.i("Debug", "onPostExecute");
            signal.countDown();
        }
    
        @Override
        protected void onCancelled() {
            super.onCancelled();
            Log.i("Debug", "onCancelled");
        }
    }
    

    编辑:我想知道在使用AndroidTestCases 和AsyncTasks 时可能会出现问题。我刚刚将您的代码复制到我的项目中并使用AsyncTask 对其进行了测试(请参阅上面的任务)。在doInBackground 之后的每次启动时,都会成功调用onPostExecute 方法。我模拟了一个长时间运行的任务,睡眠 2 分钟,这也进入了onPostExecute 方法。而在onPostExecute之后调用的tearDown方法。

    所以,您的问题可能是您的 doInBackground 方法中的一个循环。或者它以某种方式被取消并调用了任务的onCancelled 方法。

    【讨论】:

      【解决方案3】:

      我认为你的网络操作是一个非常耗时的过程,所以它需要很长时间,为什么它不能调用 onPostExecute() 方法。

      【讨论】:

      • 由于Android不允许网络操作在主线程(UI线程),我只好放到后台线程中。
      【解决方案4】:

      onPostExecute() 应该在execute() 的调用者线程中运行。如果该线程通过调用signal.await() 之类的东西被挂起,onPostExecute() 将无法运行。所以你不能在调用execute() 之后拥有signal.await()

      【讨论】:

        猜你喜欢
        • 2011-05-28
        • 2016-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-27
        • 2013-10-12
        相关资源
        最近更新 更多