2014-10-30 40 views
1

串行异步任务,所以我有一个片段执行以下操作:数据从不会显示在Android onCreateView

  1. 用途中的onCreate一个的AsyncTask从数据库条目抢JSON对象,使用标准的HTTP连接。数据稍后显示在一堆文本字段中。 (测试过,工作正常)。
  2. 在onStart中使用另一个AsyncTask以通过HTTP从另一个URL获取图像。

对于这两个任务,用onPostExecute中的子例程更新UI; TextViews和ImageView在onCreateView中初始化。

问题:该片段首次运行时,图像不显示(默认显示在它的位置,表明onPostExecute看到一个空的照片URL)。当我返回到主菜单并再次选择此活动时,所需的图像就位于其应有的位置。

我怀疑需要“刷新”,但作为一个相对异步noob,我没有任何运气识别它。有什么建议么?

编辑1:为了说明什么,我与UI做的,下面是照片异步任务的代码:

class FetchPhoto extends AsyncTask<ImageView,Void,Bitmap> { 

    ImageView imgv = null; 

    @Override 
    protected Bitmap doInBackground(ImageView... imageViews) { 

     Bitmap x = null; 
     this.imgv = imageViews[0]; 
     String tempURL = (String)imgv.getTag(); // the image's URL was previously loaded into the ImageView's tag 

     // check if URL string is empty 
     if (tempURL.equals("")) return x; 

     HttpURLConnection connection = null; 
     try { 
      URL url = new URL(tempURL); 
      connection = (HttpURLConnection) url.openConnection(); 
      InputStream input = connection.getInputStream(); 
      ByteArrayOutputStream out = new ByteArrayOutputStream(); 

      int bytesRead = 0; 
      byte[] buffer = new byte[1024]; 
      while ((bytesRead = input.read(buffer)) > 0) { 
       out.write(buffer, 0, bytesRead); 
      } 
      out.close(); 
      byte[] rawOutput = out.toByteArray(); 
      x = BitmapFactory.decodeByteArray(rawOutput, 0, rawOutput.length); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     finally { 
      connection.disconnect(); 
     } 

     return x; 
    } 

    @Override 
    protected void onPostExecute(Bitmap photo) { 

     String finalURL = (String)imgv.getTag(); 

     // update the view with the downloaded photo or the default graphic 

     if (!finalURL.equals("")) { // assumes a valid URL was used to retrieve a photo 
      imgv.setImageBitmap(photo); 
     } 
     else { 
      Bitmap bmDefault = BitmapFactory.decodeResource(getResources(), R.drawable.default_photo); 
      imgv.setImageBitmap(bmDefault); 
     } 
    } 
} 

编辑2:当我设置几个断点,我发现,异步照片任务(从onStart()调用)正在数据库任务(从onCreate()调用)中获取照片的URL之前运行。我很困惑这是如何发生的。

回答

0

您说在onPostExecute和onCreateView中更新了UI。但对于这两个AsyncTasks,它应该在onPostExecute。 这些任务根据定义是异步的,因此您知道任务完成并更新UI的唯一代码片段位于onPostExecute中。

你可以粘贴一些代码来帮助我们更好地理解你做了什么吗?

+0

完成。这个想法是,只有在onCreateView中的字段已被定义时,setupPhoto()才会运行。 DB字段的设置功能以相同的方式构建。 – 2014-10-30 21:57:11

+0

重新设计了代码以仅在onPostExecute中更新UI。 – 2014-11-17 19:10:39

0

问题是由于竞争条件造成的:任务2在任务1之前执行(没有来自任务1的所需结果)。

我通过向第一个异步任务添加接口和侦听器来解决此问题,从而创建信号量/回调机制。第二个任务仅在onFirstTaskComplete代码中调用。

我基于以下页面上的例子此解决方案:

http://kyanogen.com/asynctask-callback-android/