屏幕旋转后,Asynctask onPostExecute不会执行

时间:2014-02-04 08:11:49

标签: android android-asynctask screen-rotation

我的应用中有AsyncTask,可从网络服务器下载数据。 但是当我旋转屏幕时,我的应用程序崩溃了。这是因为第二次不执行onPostExecute(我存储下载的数据)。 但是在屏幕旋转后,onCreate()方法会运行,AsynchTask(它会)也会运行,但第二次不会调用onPostExecute。我希望你有一个解决方案。

    class ProductManager{

    public ArrayList<ProductClass> productArray;

    ProductManager(){
        Log.d("LOGTAG","TAG2"); 
            new DownloadProductTask().execute();
    }

    class DownloadProductTask extends AsyncTask<String,Integer,Void>
    {
        private ProgressDialog progressDialog = new ProgressDialog(ProductList.this);
        InputStream is = null ;
        String result = "";
        @Override
        protected void onPreExecute() {         
            progressDialog.setMessage("Download data...");
            progressDialog.show();                  
            progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface arg0) {
                    DownloadProductTask.this.cancel(true);
                   }
                });                            
        }
           @Override
        protected Void doInBackground(String... params) {   
               Log.d("LOGTAG","TAG2.1");
               String url_select = "http://jaspevj20.twenty.axc.nl/vhapp/displayproducts.php"; //Use http:// except for localhost & 127.0.0.1// jaspevj20.twenty.axc.nl for emulator local connection

          HttpClient httpClient = new DefaultHttpClient();
          HttpPost httpPost = new HttpPost(url_select);

          ArrayList param = new ArrayList();

            try {
            httpPost.setEntity(new UrlEncodedFormEntity(param));
            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();

            //read content
            is =  httpEntity.getContent();                  

            } catch (Exception e) {

            Log.e("log_tag", "Error in http connection "+e.toString());
            }
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line = "";
            while((line=br.readLine())!=null)
            {
               sb.append(line+"\n");
            }
                is.close();
                result=sb.toString();               

                    } catch (Exception e) {
                        // TODO: handle exception
                        Log.e("log_tag", "Error converting result "
                                            +e.toString());
                    }

                return null;

            }        
        @Override
        protected void onPostExecute(Void v) {                  
            // ambil data dari Json database
            try {   
                Log.d("LOGTAG","TAG3"); 
                JSONArray Jarray = new JSONArray(result);                                                                                               
                productArray = new ArrayList<ProductClass>();

                int productid;
                String productname;
                double productprice;
                int cookingtime;
                String productoptionsstring;
                List<String> productoptionslist;
                String productflavoursstring;
                List<String> productflavourslist;
                String productdescription;
                String category;
                List<String> categorylist;


                for(int i=0;i<Jarray.length();i++)
                            {                                                                                                                           
                                 JSONObject Jasonobject = null;                                                              
                                 Jasonobject = Jarray.getJSONObject(i);
                                 productid = Integer.parseInt(Jasonobject.getString("ProductId"));
                                 productname = Jasonobject.getString("ProductName");
                                 productprice = Double.parseDouble(Jasonobject.getString("ProductPrice"));                                       
                                 cookingtime = Integer.parseInt(Jasonobject.getString("CookingTime"));
                                 productoptionsstring = Jasonobject.getString("ProductOptions");    
                                 productoptionslist = Arrays.asList(productoptionsstring.split("\\s*,\\s*"));
                                 productflavoursstring = Jasonobject.getString("ProductFlavours");
                                 productflavourslist = Arrays.asList(productflavoursstring.split("\\s*,\\s*"));
                                 productdescription = Jasonobject.getString("ProductDescription");
                                 category = Jasonobject.getString("Category");
                                 categorylist = Arrays.asList(category.split("\\s*,\\s*"));
                                 Log.d("LOGTAG","TAG4"); 
                                 productArray.add(new ProductClass(productid,productname,productprice,cookingtime));     
                                 ProductClass product = productArray.get(productArray.size()-1);                                     
                                 product.setProductOptions(productoptionslist);
                                 product.setFlavours(productflavourslist);
                                 product.setDescription(productdescription);
                                 product.setCategories(categorylist);                                    
                            }

                mTitle = mDrawerTitle = getTitle();
                mCategoryTitles = mProductManager.getAllCategories();                                       
                // set a custom shadow that overlays the main content when the drawer opens
                mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
                mDrawerList.setAdapter(new ArrayAdapter<String>(ProductList.this,
                        R.layout.drawer_list_item, mCategoryTitles));
                mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
                // Select the first category displaying as default
                selectItem(0);              
                this.progressDialog.dismiss();                                                                                  
                     } 
            catch (Exception e) 
            {
                Log.e("log_tag", "Error parsing data "+e.toString());
            }   
        }
    }

2 个答案:

答案 0 :(得分:2)

实际上更可能的是你的AsyncTask确实执行了,而onPostExecute使用的是对Android销毁的小部件(来自之前的Activity实例)的引用。由于您的DownloadProductTask是您的Activity的内部,它包含对您的Activity的隐式引用,并且它不允许释放您的活动。

如果你不想使用android:configChanges hack - 然后使你的AsyncTask静态,然后使用onRetainNonConfigurationInstance / getLastNonConfigurationInstance保留你的AsyncTask实例,并在onCreate中使用新的小部件更新你的AsyncTask进行更新。这实际上是短篇小说,相当复杂。其他选项 - IMO更容易将AsyncTask放入保留的片段中。以下是一些信息:

Android Fragments. Retaining an AsyncTask during screen rotation or configuration change

使用android:configChanges的问题是,当你的Activity在正常的LifeCycle变化中被破坏时,它不会保护你,即。你称之为AsyncTask,然后你隐藏你的活动,然后转到其他一些活动 - Android现在可以自由地销毁你的活动 - 导致同样的问题。

答案 1 :(得分:0)

使用捆绑包保存您的数据。或者使用

编辑所需活动的清单

如果有异步任务,我建议你使用第一种方法

android:configChanges="orientation|keyboardHidden"

Bundle简介:

 @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
      super.onSaveInstanceState(savedInstanceState);
      // Save UI state changes to the savedInstanceState.
      // This bundle will be passed to onCreate if the process is
      // killed and restarted.
      savedInstanceState.putBoolean("MyBoolean", true);
      savedInstanceState.putDouble("myDouble", 1.9);
      savedInstanceState.putInt("MyInt", 1);
      savedInstanceState.putString("MyString", "Welcome back to Android");
      // etc.
    }

Bundle本质上是一种存储NVP(“名称 - 值对”)地图的方式,它将被传递到onCreate以及onRestoreInstanceState,您可以在其中提取值这样:

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  // Restore UI state from the savedInstanceState.
  // This bundle has also been passed to onCreate.
  boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
  double myDouble = savedInstanceState.getDouble("myDouble");
  int myInt = savedInstanceState.getInt("MyInt");
  String myString = savedInstanceState.getString("MyString");
}