2016-05-05 19 views
1

這是我第一次編寫Android代碼,並且我遇到了一個問題。AsyncTask請求數據晚於我創建按鈕取決於這些數據

在MainActivity中,我使用AsyncTask來請求「類別」列表來創建按鈕。可以單擊MainActivity按鈕,並使用額外字符串「Category(例如drink)」重定向到GetProductsActivity。在GetProductsActivity中,我再次請求服務器使用「類別」獲取「產品」列表來創建產品按鈕。

這裏是問題:代碼先創建按鈕,然後AsyncTask請求服務器獲取「產品」列表,我想在創建按鈕之前獲取「產品」列表。我該怎麼辦?

「orga.getAttributes」是請求服務器的函數。 這裏是MainActivity

public class MainActivity extends AppCompatActivity { 
    private ArrayList<String> data = new ArrayList<String>(); 
    List<String> attributes = new ArrayList<String>(); 
    List<String> categoryList = new ArrayList<String>(); 
    final Organisation orga = Organisation.getInstance(); 
    private class CallSocketTask extends AsyncTask<Integer, Integer, String> { 

     protected String doInBackground(Integer... nochnix) { 

      orga.SetInit(); 
      categoryList = orga.getAttributes(orga.GET_CATEGORIES,null,true); 

      return null; 
     } 

     protected void onPostExecute(String string) { 
      //attributes = orga.getAttributes(orga.GET_PRODUCTS_BY_CATEGORY,null,true); 
     } 
    } 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     new CallSocketTask().execute();//orga.stop(); 
     //requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 
     setContentView(R.layout.activity_main); 
     LinearLayout layer = (LinearLayout) findViewById(R.id.layer); 
     //getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.activity_main); 
     for(int i=0; i < categoryList.size(); i++) 
     { 
      Button button = new Button(this); 
      button.setId(i); 
      final String category = categoryList.get(i); 
      button.setText(category); 
      //click action 
      View.OnClickListener productHandler = new View.OnClickListener(){ 
       public void onClick(View v) { 
        // doStuff 
        Intent intentMain = new Intent(MainActivity.this , 
          GetProductsActivity.class); 
        intentMain.putExtra("categroy",category); 
        MainActivity.this.startActivity(intentMain); 
        Log.i("Content "," Main layout Click to Get Products by Category"); 

       } 
      }; 
      button.setOnClickListener(productHandler); 
      layer.addView(button); 
     } 
    } 
} 

這裏是GetProductsActivity

public class GetProductsActivity extends AppCompatActivity{ 
    private ArrayList<String> data = new ArrayList<String>(); 
    List<String> attributes = new ArrayList<String>(); 
    final Organisation orga = Organisation.getInstance(); 
    String category; 

    private class CallSocketTask extends AsyncTask<Integer, Integer, String> { 


     protected String doInBackground(Integer... nochnix) { 
      Bundle extras = getIntent().getExtras(); 
      if (extras != null) { 
       category = extras.getString("categroy"); 
       Log.i("Category Selected",category); 
      } 
      //orga.SetInit(); 
      attributes = orga.getAttributes(orga.GET_PRODUCTS_BY_CATEGORY,category); 
      Log.i("Product number ",attributes.size()+""); 
      //attributes = orga.getAttributes("getProducts","getCategories","Orangensaft"); 
      return null; 
     } 

     protected void onPostExecute(String string) { 
      //Log.i("Result ",""); 
     } 
    } 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     //this.notifyAll(); 
     CallSocketTask myTask = new CallSocketTask(); 
     myTask.execute();//orga.stop(); 
     setContentView(R.layout.get_products); 
     LinearLayout layer = (LinearLayout) findViewById(R.id.productsLayer); 
     //getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.activity_main); 
     //Bundle extras = getIntent().getExtras(); 
     //data= extras.getStringArrayList("products"); 
     Log.i("Product number OnCreate",attributes.size()+""); 
     for(int i=0; i < attributes.size(); i++) 
     { 
      Log.i("Product",attributes.get(i)); 
      Button button = new Button(this); 
      button.setId(i); 
      button.setText(attributes.get(i)); 

      layer.addView(button); 
     } 
    } 
} 

回答

0

移動你的代碼的按鈕設置成onPostExecute。

+0

這會導致一個問題,即新的Button(this),如何處理「this」。 –

+0

我認爲這是根據情況最合適的答案。並回答那玉琦:在這個例子中,你可以調用'new Button(MainActivity.this)'。請記住''onPostExecute()'在主線程上運行。你不應該從這裏執行任何長時間的阻塞任務。 – dbm

+0

是的,你是對的。謝謝。 –

0

解決這個問題很簡單:在onCreate()函數中使用Thread.sleep(),所以循環按鈕可以等待AsyncTask運行。

+0

我真的建議不要這樣做:'onCreate()'在主線程上運行,永遠不應該阻塞主線程。然後就是'Thread.sleep()'的東西,這也應該是最後的手段,因爲有更好的方法來等待任務完成。 – dbm

+0

是的,你是對的。 –

0

非靜態內部AsyncTask可能導致內存泄漏,請檢查一些gotchas

Thread.sleep()是一個不好的方法。如果請求「類別」由於網絡問題而延長運行時間會怎樣?

按鈕可以在應該在onPostExecute()中調用的方法YourActivity.createButtons()中創建。

+0

是的,你是對的。 –