2016-04-17 8 views
0

Ich bin erfolgreich Abrufen, Analysieren und Auffüllen von Ansichten aus den Daten von JSON erhalten.Wie speichere/restauriere ich die Bilder, die von json über Konfigurationsänderungen heruntergeladen wurden

Aber es gibt einen Fehler, der die App plagt: Unfähigkeit, die aufgefüllten Daten nach Konfigurationsänderung zu speichern und wiederherzustellen.

Ich kann Strings erfolgreich speichern und wiederherstellen, aber Bilder und formatierte HTML ist mein Problem.

Dies ist mein Code

public class FruitDetails extends AppCompatActivity{ 

    private final String TAG = "FruitDetails"; 

    protected com.nostra13.universalimageloader.core.ImageLoader mImageLoader; 


    TextView fruitTitle, fruitAuthorDate, fruitContent; 
    CircularNetworkImageView authorImg; 
    ImageLoader AuthImgLoader; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_fruit_details); 



     fruitTitle = (TextView) findViewById(R.id.dfruit_title); 
     fruitAuthorDate = (TextView) findViewById(R.id.author_date); 
     fruitContent = (TextView) findViewById(R.id.dfruit_content); 
     authorImg = (CircularNetworkImageView) findViewById(R.id.author_img); 


     mImageLoader = com.nostra13.universalimageloader.core.ImageLoader.getInstance(); 
     mImageLoader.init(ImageLoaderConfiguration.createDefault(this)); 

     ActionBar actionBar = getSupportActionBar(); 
     if (actionBar != null) { 
      actionBar.setDisplayHomeAsUpEnabled(true); 
     } 



     if (savedInstanceState != null) { 
      fruitTitle.setText(savedInstanceState.getString("fruitTitle")); 
      fruitAuthorDate.setText(savedInstanceState.getString("posAuthorDate")); 
      fruitContent.setText(savedInstanceState.getString("fruitContent")); 
      //fruitAuthorDate.setPar 

      //Unhiding views 
      fruitTitle.setVisibility(View.VISIBLE); 
      fruitAuthorDate.setVisibility(View.VISIBLE); 
      fruitContent.setVisibility(View.VISIBLE); 
      authorImg.setVisibility(View.VISIBLE); 


     } else { 
      if (NetworkCheck.isAvailableAndConnected(this)) { 
       //Calling method to load fruits 
       loadFruit(); 
      } else { 
       final Context context; 
       context = this; 
       final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this); 
       alertDialog.setTitle(R.string.alert_titl); 
       alertDialog.setCancelable(false); 
       alertDialog.setIcon(R.mipmap.ic_launcher); 
       alertDialog.setMessage(R.string.failed_fruit); 
       alertDialog.setPositiveButton(R.string.alert_retry, new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         if (!NetworkCheck.isAvailableAndConnected(context)) { 
          alertDialog.show(); 
         } else { 
          loadFruit(); 
         } 
        } 
       }); 
       alertDialog.setNegativeButton(R.string.alert_cancel, new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 
         finish(); 
        } 
       }); 
       alertDialog.show(); 
      } 
     } 
    } 

    private void loadFruit() { 
     Log.d(TAG, "loadFruit called"); 

     final ProgressBar progressBar; 
     progressBar = (ProgressBar) findViewById(R.id.progress_circle); 
     progressBar.setVisibility(View.VISIBLE); 


     int news_id = getIntent().getIntExtra("FruitId", -1); 
     Log.d(TAG, "You clicked fruit id " + news_id); 

     final JsonObjectRequest jsonObjReq = new JsonObjectRequest(DetailConfig.GET_DURL + news_id, null, 


       new Response.Listener<JSONObject>() { 
        @Override 
        public void onResponse(JSONObject response) { 
         Log.d("Debug", response.toString()); 

         //Unhiding views 
         fruitTitle.setVisibility(View.VISIBLE); 
         fruitAuthorDate.setVisibility(View.VISIBLE); 
         fruitContent.setVisibility(View.VISIBLE); 
         authorImg.setVisibility(View.VISIBLE); 


         //Dismissing progressbar; 
         if (progressBar != null) { 
          progressBar.setVisibility(View.GONE); 
         } 

         //Calling method to parse json array 
         parseFruit(response); 
        } 
       }, 
       new Response.ErrorListener() { 
        @Override 
        public void onErrorResponse(VolleyError error) { 
         VolleyLog.d("", "Error: " + error.getMessage()); 
        } 
       }); 

     //Creating request queue 
     RequestQueue requestQueue = Volley.newRequestQueue(this); 

     //Adding request to queue 
     requestQueue.add(jsonObjReq); 
    } 

    //This method will parse json data of fruit 
    private void parseFruit(JSONObject jsonObject) { 

     Log.d(TAG, "Parsing fruit"); 


      try { 
       String title = jsonObject.getString(DetailConfig.TAG_DFRUIT_TITLE); 
       fruitTitle.setText(Html.fromHtml(title)); 

       JSONObject pAuthor = jsonObject.getJSONObject("author"); 
       String author = pAuthor.getString("name"); 
       String authorimg = pAuthor.getString("avatar"); 

       AuthImgLoader = VolleyRequest.getInstance(getApplicationContext()).getImageLoader(); 
       AuthImgLoader.get(authorimg, ImageLoader.getImageListener(authorImg, R.drawable.ic_author, R.drawable.ic_author)); 
       authorImg.setImageUrl(authorimg, AuthImgLoader); 


       SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMMM, yyyy"); 
       SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 
       String inputDateStr = jsonObject.getString(DetailConfig.TAG_DFRUIT_DATE); 
       try { 
        Date inputDate = inputFormat.parse(inputDateStr); 
        String date = dateFormat.format(inputDate); 
        Resources resources = getResources(); 
        String authdate= String.format(resources.getString(R.string.fruit_by), author, date); 
        fruitAuthorDate.setText(authdate); 
       } catch (ParseException e) { 
        Log.d(TAG, "Error in parsing date"); 
       } 

       String content = jsonObject.getString(DetailConfig.TAG_DFRUIT_CONTENT); 
       Spanned spanned = Html.fromHtml(content, new UILImageGetter(fruitContent, this), null); 
       fruitContent.setText(spanned); 

      } catch (JSONException w) { 
       w.printStackTrace(); 
      } 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putString("fruitTitle", fruitTitle.getText().toString()); 
     outState.putString("posAuthorDate", fruitAuthorDate.getText().toString()); 
     outState.putString("fruitContent", fruitContent.getText().toString()); 
     //Doesn't work --> outState.putParcelable("fruitAuthor", (Parcelable) fruitAuthorDate); 
    } 

    @Override 
    public boolean onSupportNavigateUp() { 
     onBackPressed(); 
     return true; 
    } 

} 

Aus dem obigen Code I und wiederherstellen fruitTitle und fruitAuthorDate, weil sie nur Zeichenfolgen enthalten speichern können. Für fruitContent enthält es Text Spanned, formatiert mit Html.fromHtml, und enthält heruntergeladene Bilder, so dass der obige Code nur Strings und Strings allein speichern und wiederherstellen kann. Nach der Wiederherstellung wird der formatierte Text Html.fromHtml durch unformatierte Zeichenfolge ersetzt und die Bilder sind weg!

Für fruitAuthorDate konnte ich es überhaupt nicht speichern. Ich habe Paralabel versucht, wie Sie oben sehen können, aber die App ist abgestürzt.

Also, meine Frage ist, wie speichere ich diese Bilder und formatierten HTML-Text, wenn der Bildschirm gedreht wird?

Antwort

1

Anstatt einzelne Felder Ihrer JSON-Daten zu speichern, können Sie einfach die gesamte JSONObject, die Sie von der Anfrage erhalten, speichern.

In Ihrem onResponse() Rückruf von dem JsonObjectRequest Sie speichern Sie nur JSONObject zu einem Feld, das ich fruitData nennen würde:

new Response.Listener<JSONObject>() { 
    @Override 
    public void onResponse(JSONObject response) { 
     ... 

     fruitData = response; // where fruitData is a JSONObject field of your activity 

     parseFruit(response); 
    } 
} 

Dann in onSaveInstanceState() Sie einfach die JSONObject fruitData als String auf das Bündel speichern.

protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    outState.putString("fruitData", fruitData.toString()); 
} 

die Daten wiederherzustellen, können Sie die Daten zurück in onCreate() bekommen können, wie Sie bereits mit den einzelnen Feldern tun, und parseFruit() auf ihn nennen, als ob Sie es vorher heruntergeladen haben:

protected void onCreate(Bundle savedInstanceState) { 
    ... 

    if (savedInstanceState != null) { 
     try { 
      String fruitDataStr = savedInstanceState.getString("fruitData"); 
      fruitData = new JSONObject(fruitDataStr); 

      parseFruit(fruitData); 
     } 
     catch (JSONException e) { } 

     //Unhiding views 
     fruitTitle.setVisibility(View.VISIBLE); 
     fruitAuthorDate.setVisibility(View.VISIBLE); 
     fruitContent.setVisibility(View.VISIBLE); 
     authorImg.setVisibility(View.VISIBLE); 
    } 
    ... 
} 

On Eine Randnotiz: Ich würde die Logik "Ansichten einblenden" in die parseFruit()-Methode einfügen, also haben Sie diesen Code nur einmal, nicht zweimal so wie jetzt in onCreate() und onResponse().

+0

Wo und wie soll ich 'fruitData' Feld angeben? – X09

+0

@Ozun genau wie 'ImageLoader AuthImgLoader;' am Anfang Ihrer 'FruitDetails' Aktivität, zum Beispiel' private JSONObject fruitData; ' – Floern

+0

Ich habe diese' private String fruitData' vor 'onCreate' gemacht und Android Studio begann sich über" Inkompatibel "zu beklagen Typen "in line" fruitData = Antwort; ' – X09

Verwandte Themen