2016-05-23 98 views
0

我想從一個異步任務類到另一個片段類的數組,但我得到一個空指針異常。我在這裏看到了很多答案,但我沒有看到實際回答這個問題。Android將數組從異步任務傳遞到另一個類

我試圖從異步類任務返回值,我試圖使數組靜態,但我沒有成功。

這些都是班(我強調了在那裏我想從價值,並把它):

public class DemoPreviewSongFragment extends DemoFragmentBase { 
     // The DynamoDB object mapper for accessing DynamoDB. 
     private final DynamoDBMapper mapper; 
     public DemoPreviewSongFragment() { 
      mapper = AWSMobileClient.defaultMobileClient().getDynamoDBMapper(); 
     } 

     SongPreviewCardsDataAdapter mCardAdapter; 
     com.wenchao.cardstack.CardStack mCardStack; 

     @Override 
     public View onCreateView(final LayoutInflater inflater, final ViewGroup container, 
           final Bundle savedInstanceState) { 
      View view = inflater.inflate(R.layout.fragment_preview_song, container, false); 
      mCardStack = (CardStack)view.findViewById(R.id.cardstackcontainer); 
      mCardStack.setContentResource(R.layout.song_preview_card_layout); 
      mCardStack.setStackMargin(20); 

      new getSongsInCategory().execute(); 

/////////// WHEN TRYING TO REFERENCE THE STATIC ARRAY RESULT HERE I GET A NULL /////////// POINTER. I NEED THE ARRAY HERE SO I CAN PUT IT IN THE ADAPTER. 

      mCardAdapter = new SongPreviewCardsDataAdapter(getActivity().getApplicationContext(),0); 
      mCardAdapter.add("test1"); 

      mCardStack.setAdapter(mCardAdapter); 

      return view; 
     } 



//////////////////// THIS IS THE ARRAY I AM TRYING TO PASS ///////////////////// 
     public static PaginatedQueryList<SongDatabaseMappingAdapter> result; 

     public class getSongsInCategory extends AsyncTask { 

      @Override 
      protected Object doInBackground(Object[] params) { 

       SongDatabaseMappingAdapter songs = new SongDatabaseMappingAdapter(); 
       songs.setCategory("Rap"); 

       String userRatingQueryString = "5"; 

       Condition rangeKeyCondition = new Condition() 
         .withComparisonOperator(ComparisonOperator.EQ) 
         .withAttributeValueList(new AttributeValue().withN(userRatingQueryString)); 

       DynamoDBQueryExpression queryExpression = new DynamoDBQueryExpression() 
         .withHashKeyValues(songs) 
         .withIndexName("Category-UserRating-index") 
         .withRangeKeyCondition("UserRating", rangeKeyCondition) 
         .withConsistentRead(false); 

       result = mapper.query(SongDatabaseMappingAdapter.class, queryExpression); 
       return result; 
      } 
    } 

我不知道我在做什麼錯在這裏爲什麼是一個空指針當它應該是一個全局(靜態)數組?有沒有更好的方法來做到這一點? AsynTask的

感謝您的幫助

回答

1

好了,所以你要明白的AsyncTask原理,簡單地說,它運行的一些東西在不同的線程,而不是阻塞當前線程,並沒有阻止這意味着它會自動轉到下一行在調用execute之後,不依賴asynk任務中任務的持續時間,也不等待任務完成。

你的情況:

new getSongsInCategory().execute(); // here you call the task to generate the result 
result.doSomething() // this line will be called before your task is completed, so the result won't be initialized => NPE 

你應該把它用Observer模式(回調)這樣做的方式。你設置一個觀察者到你的AsyncTask中來找出它的完成時間。完成後,它會通知觀察任務的對象。

這樣的例子可能是這樣的:

public class DemoPreviewSongFragment extends DemoFragmentBase implements AwesomeObserver { 
public interface AwesomeObserver { 
    void theTaskIsDone(Object theTaskResult); 
} 

public View onCreateView(final LayoutInflater inflater, final ViewGroup container, 
          final Bundle savedInstanceState) { 
... 
new GetSongsInCategory(this).execute(); 

//新的最佳實踐是 新GetSongsInCategory(本).executeOnExecutor(THREAD_POOL_EXECUTOR); }

@Override 
theTaskIsDone(Object theTaskResult) { 
    theTaskResult.doSomething(); 
    //In your case 
     mCardAdapter = new SongPreviewCardsDataAdapter(getActivity().getApplicationContext(),0); 
     mCardAdapter.add("test1"); 

     mCardStack.setAdapter(mCardAdapter); 
} 

public class GetSongsInCategory extends AsyncTask { 
    private AwesomeObserver observer; 
    public GetSongsInCategory(AwesomeObserver someone) { 
     observer = someone; 
    } 
// doInBackground ....and do things 

public void onPostExecute(Object object) { 
    // at this point you know the task is done 
    if(observer != null) 
    observer.theTaskIsDone(object); 
    } 
} 

}

現在,爲了避免混淆,在theTaskIsDone & onPostExecute參數只是一個例子,你可以使用任何它適合你的榜樣。 這實際上是一種通用的方式,您也可以從onPostExecute調用異步任務的包含類中的方法,但是如果您在單獨的java文件中有內部異步任務或異步任務,則此方法將工作。

2

集數據適配器onPostexecute()方法。你會得到例外,因爲你沒有得到任何數據是適配器。 AsynTask在後臺執行操作,可能是在AsyncTask完成之前使用這些值的情況。所以在onPostExecute中設置適配器。

doInBackground(){ 
} 
onPostExecute(){ 

// use result array here and set it on adapter 
} 
1

的AsyncTask是異步的,從而該陣列是當的AsyncTask通過在OnPostExecute()方法完成的訪問可以null.You更新適配器。

這是我改變了邏輯現在它將工作的代碼。

public class DemoPreviewSongFragment extends DemoFragmentBase { 
    // The DynamoDB object mapper for accessing DynamoDB. 
    private final DynamoDBMapper mapper; 
    public DemoPreviewSongFragment() { 
     mapper = AWSMobileClient.defaultMobileClient().getDynamoDBMapper(); 
    } 

    SongPreviewCardsDataAdapter mCardAdapter; 
    com.wenchao.cardstack.CardStack mCardStack; 

    @Override 
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container, 
          final Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_preview_song, container, false); 
     mCardStack = (CardStack)view.findViewById(R.id.cardstackcontainer); 
     mCardStack.setContentResource(R.layout.song_preview_card_layout); 
     mCardStack.setStackMargin(20); 

     new getSongsInCategory().execute(); 

     return view; 
    } 

    public class getSongsInCategory extends AsyncTask { 

     @Override 
     protected Object doInBackground(Object[] params) { 

      SongDatabaseMappingAdapter songs = new SongDatabaseMappingAdapter(); 
      songs.setCategory("Rap"); 

      String userRatingQueryString = "5"; 

      Condition rangeKeyCondition = new Condition() 
        .withComparisonOperator(ComparisonOperator.EQ) 
        .withAttributeValueList(new AttributeValue().withN(userRatingQueryString)); 

      DynamoDBQueryExpression queryExpression = new DynamoDBQueryExpression() 
        .withHashKeyValues(songs) 
        .withIndexName("Category-UserRating-index") 
        .withRangeKeyCondition("UserRating", rangeKeyCondition) 
        .withConsistentRead(false); 

     return mapper.query(SongDatabaseMappingAdapter.class, queryExpression); 

     } 

     @Override 
     public void onPostExecute(Object obj){ 

     //Here array will not be null. 

     PaginatedQueryList<SongDatabaseMappingAdapter> result=(PaginatedQueryList<SongDatabaseMappingAdapter>)obj; 
     mCardAdapter = new SongPreviewCardsDataAdapter(getActivity().getApplicationContext(),result[0]); 
     mCardAdapter.add("test1"); 

     mCardStack.setAdapter(mCardAdapter); 

     } 

    } 
相關問題