2014-03-18 50 views
1

我需要一些幫助來解決這個問題。我有一個PieChart,它在我的Android應用程序中使用來自MySQLdb的一些數據繪製。我正在使用AsyncTask類實現,它從服務器加載數據,製作HTTPPostRequest並解析返回的JSON響應。圖表出來很好,並在屏幕上繪製。當我旋轉設備的屏幕時出現問題:圖表行爲異常並再次繪製切片...我不知道爲什麼它會這樣做,但我讀到如果旋轉屏幕調用Activity的所有方法再次(onCreate()onStart()onResume()方法)。也許是因爲這個?但我不知道......這是怎麼樣子:爲什麼我的Android PieChart繪圖行爲異常,並且屏幕旋轉中出現重複的片段?

enter image description here

然後,當我旋轉設備:

enter image description here

的數據被複制!爲什麼?我錯在哪裏?

這裏是所有代碼:

public class ComeHaInvestito extends Activity { 

/**** PieChartBuilder ****/ 
/** Colors to be used for the pie slices. */ 
private static int[] COLORS = new int[] { Color.GREEN, Color.BLUE, Color.MAGENTA, Color.CYAN }; 
/** The main series that will include all the data. */ 
private CategorySeries mSeries = new CategorySeries(""); 
/** The main renderer for the main dataset. */ 
private DefaultRenderer mRenderer = new DefaultRenderer(); 
/** Edit text field for entering the slice value. */ 
//private EditText mValue; 
/** The chart view that displays the data. */ 
private GraphicalView mChartView; 

private int HowmanyTimes; 
@Override 
protected void onRestoreInstanceState(Bundle savedState) { 
    super.onRestoreInstanceState(savedState); 
    mSeries = (CategorySeries) savedState.getSerializable("current_series"); 
    mRenderer = (DefaultRenderer) savedState.getSerializable("current_renderer"); 
} 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    outState.putSerializable("current_series", mSeries); 
    outState.putSerializable("current_renderer", mRenderer); 
    } 

/**** ComeHaInvestito ****/ 
// String which will store the values of the user 
String municipalityName; 
String year; 
String versedMoney; 

// List<Item> ArrayList that will be used to store data from DB 
List<Item> MasterAndDetailstatisticsInfoList; 

private static final String TAG_COMUNE = "mun_name"; 
private static final String TAG_ANNO = "year"; 
private static final String TAG_VERSED_MONEY = "versed_money"; 
private static final String TAG_SUCCESS = "success"; 

// POST request information 
private static final String URL_ANDROID_APP_LISTENER = "http://xxx.xxx.xxx.xxx/androidApp/AndroidListener.php"; 

private ProgressDialog pDialog; 
// JSONParser instance 
JSONParser jParser = new JSONParser(); 

// JSON data retrieving information 
private static final String JSON_STATISTICS_INFOS_LABEL = "statistics_infos"; 
private static final String JSON_MASTER_LABEL = "master"; 
private static final String JSON_DETAIL_LABEL = "detail"; 
private static final String JSON_MASTER_DETAIL_NAME_LABEL = "name"; 
private static final String JSON_MASTER_DETAIL_VALUE_LABEL ="value"; 

// statistics info JSON Array which will contain the Master and Detail data that will come from the POST request 
JSONArray statisticsInfo = null; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_come_ha_investito); 
    Log.d("OnCREATE", "CREO L'ACTIVITY"); 
    // recovering data from previous actitity 
    Intent iMieiDati = getIntent(); 
    this.municipalityName = iMieiDati.getStringExtra(TAG_COMUNE); 
    this.year = iMieiDati.getStringExtra(TAG_ANNO); 
    this.versedMoney = iMieiDati.getStringExtra(TAG_VERSED_MONEY); 

    // instantiating the needed data structure 
    MasterAndDetailstatisticsInfoList = new ArrayList<Item>(); 

    mRenderer.setStartAngle(270); 
    mRenderer.setDisplayValues(true); 

    new LoadAllMunicipalitiesInvestmentStatisticsThread().execute(); 

    //mRenderer.setZoomButtonsVisible(true); 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.pie_chart_builder2, menu); 
    return true; 
} 

@Override 
protected void onResume() { 
    super.onResume(); 

    if (mChartView == null) { 
     LinearLayout layout = (LinearLayout) findViewById(R.id.chart); 
     mChartView = ChartFactory.getPieChartView(this, mSeries, mRenderer); 
     mRenderer.setClickEnabled(true); 
     mChartView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      SeriesSelection seriesSelection = mChartView.getCurrentSeriesAndPoint(); 
      if (seriesSelection == null) { 
      Toast.makeText(ComeHaInvestito.this, "No chart element selected", Toast.LENGTH_SHORT).show(); 
      } 
      else { 
      for (int i = 0; i < mSeries.getItemCount(); i++) { 
       mRenderer.getSeriesRendererAt(i).setHighlighted(i == seriesSelection.getPointIndex()); 
      } 
      // mChartView.repaint(); 

      Toast.makeText(
       ComeHaInvestito.this, 
       "Chart data point index " + seriesSelection.getPointIndex() + " selected" 
        + " point value=" + seriesSelection.getValue(), Toast.LENGTH_SHORT).show(); 

      } 
     } 
     }); 
     layout.addView(mChartView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 
    } 
    else { 
     //mChartView.repaint(); 
    } 
    } 


    private void initChart() { 
     int i=0; 
     double value=0; 
     for (Item item : MasterAndDetailstatisticsInfoList) { 
      if (i == 4) { 
       break; 
      } 
      Log.d("Ciclo ", "NUMERO " + i); 
      if (item.getViewType() == EntryType.MASTER.ordinal()) { 
       MasterWithValue master = (MasterWithValue) item; 
       Log.d("MASTER NAME", master.getMasterName()); 
       Log.d("MASTER VALUE", master.getMasterValue()); 
       try { 
        value = Double.parseDouble(master.getMasterValue()); 
       } 
       catch (NumberFormatException e) { 
        // value is not a decimal 
       } 
       mSeries.add(master.getMasterName(), value); 
       SimpleSeriesRenderer renderer = new SimpleSeriesRenderer(); 
       renderer.setColor(COLORS[i%4]); 
       i++; 
       mRenderer.addSeriesRenderer(renderer); 
       Log.d("mSeries", mSeries.toString()); 
      } 
     } 
    } 

/**** Background Thread ****/ 
public class LoadAllMunicipalitiesInvestmentStatisticsThread extends AsyncTask<String, String, String> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     pDialog = new ProgressDialog(ComeHaInvestito.this); 
     pDialog.setMessage("Caricamento..."); 
     pDialog.setIndeterminate(false); 
     pDialog.setCancelable(false); 
     pDialog.show();   
    } 

    @Override 
    protected String doInBackground(String... args) { 
     Log.d("ilMioComune", "Caricamento Statistiche Investimenti"); 
     // building the HTTP POST request 
     List<NameValuePair> params = new ArrayList<NameValuePair>(); 
     params.add(new BasicNameValuePair(TAG_COMUNE, municipalityName)); 
     params.add(new BasicNameValuePair(TAG_ANNO, year)); 
     params.add(new BasicNameValuePair(TAG_VERSED_MONEY, versedMoney)); 
     Log.d("params", params.toString()); 
     JSONObject json = jParser.makeHttpRequest(URL_ANDROID_APP_LISTENER, "POST", params); 

     Log.d("JSON POST statistics investments", json.toString()); 
     try { 
      int success = json.getInt(TAG_SUCCESS); 

      if (success == 1) { 

       statisticsInfo = json.getJSONArray(JSON_STATISTICS_INFOS_LABEL); 

       // foreach Statistics Master Entry 
       for (int i = 0; i<statisticsInfo.length(); i++) { 
        JSONObject JSONstatisticsInfo = statisticsInfo.getJSONObject(i); 
        JSONObject JSONmasterEntry = JSONstatisticsInfo.getJSONObject(JSON_MASTER_LABEL); 

        String masterEntryName = JSONmasterEntry.getString(JSON_MASTER_DETAIL_NAME_LABEL); 
        String masterEntryValue = JSONmasterEntry.getString(JSON_MASTER_DETAIL_VALUE_LABEL); 
        MasterAndDetailstatisticsInfoList.add(new MasterWithValue(masterEntryName, masterEntryValue));      

        JSONArray JSONdetails = JSONmasterEntry.getJSONArray(JSON_DETAIL_LABEL); 
        for (int j = 0; j<JSONdetails.length(); j++) { 
         JSONObject JSONdetailEntry = JSONdetails.getJSONObject(j); 

         String detailEntryName = JSONdetailEntry.getString(JSON_MASTER_DETAIL_NAME_LABEL); 
         String detailEntryValue = JSONdetailEntry.getString(JSON_MASTER_DETAIL_VALUE_LABEL); 

         MasterAndDetailstatisticsInfoList.add(new Detail(detailEntryName, detailEntryValue)); 
        } 
       } 
      } 
      else { 
       // no statistics infos associated to the selected municipality were found 
      } 
     } 
     catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String file_url) { 
     pDialog.dismiss(); 

     runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       String MasterAndDetails = MasterAndDetailstatisticsInfoList.toString(); 
       Log.d("List", MasterAndDetails); 

       // Creating the pie chart using the data recovered from the DB 
       initChart(); 
      } 
     }); 
    } 
} 
} 

有沒有人對如何解決這個問題的任何想法?

感謝您的關注!希望得到一些幫助!

回答

0

你是正確的,onCreate()onResume()等等,每當你旋轉時得到調用。正因爲如此,您實際上撥打new LoadAllMunicipalitiesInvestmentStatisticsThread().execute();兩次。

您應該將數據初始化邏輯移動到一個位置,並從savedInstanceState加載該數據,或者如果savedInstanceState返回null,則調用初始化邏輯。

例如:

改變聲明

private CategorySeries mSeries = null;

onCreate()

if(savedInstanceState != null) 
    mSeries = (CategorySeries) savedInstanceState.getSerializable("current_series"); 

if(mSeries == null) 
{ 
    mSeries = new CategorySeries(""); 
    new LoadAllMunicipalitiesInvestmentStatisticsThread().execute(); //this line can be substituted for a new init method, which would contain the thread.execute 
} 
+0

我在我的onCreate()方法中添加這些行,但我得到一個Java空指針異常,在行 - mSeries =(CategorySeries)savedInstanceState.getSerializable(「current_series」); - 我試圖把這些行放在--super.onCreate(savedInstanceState)之前和之後; - 在onCreate()方法的開始處調用。我應該知道什麼? – tonix

+0

有沒有辦法解決這個問題? – tonix

+0

檢查savedInstanceState是否爲null,如果未從保存的實例中調用onCreate(即第一次啓動活動),它將爲null。編輯我的答案。 – invertigo

相關問題