2014-07-18 1 views
1

약간의 saveInstanceState 문제가 있습니다.NullPointer 예외 인 스턴스 문자열을 인스턴스 상태로 저장 Android

하나의 활동은 인 텐트를 통해 문자열 값을 다른 활동으로 보내며 이는 환상적으로 작동합니다. 이제 두 번째 활동에서 하나의 행 항목을 선택하여 세 번째 활동으로 넘어갑니다. 그러나 두 번째 작업에 액션 바 BACK 버튼을 사용하면 NullPointerException이 발생합니다.

이유는 물론 첫 번째 활동의 의도 문자열을로드 할 수 없기 때문입니다. 그래서 두 번째 활동에서이 인 텐트 문자열 값을 인스턴스 상태로 저장하고이 값을 oncreate methode에서 다시 얻으려고했습니다. 나는 많이 googlet했습니다, 나는 많이 시도했습니다. 그러나 Nullpointer는 사라지지 않을 것입니다.

약간의 힌트가 있으면 좋을 것입니다.

은 첫째, 실제로 savedInstanceState를 사용하지 않은 : 두 번째 활동의

내 코드 : 내가 볼 수

package de.cityknight.app; 

import android.app.Activity; 
import android.content.Context; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ListView; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.List; 


public class RouteChooseActivity extends ActionBarActivity implements OnItemClickListener { 

    String citySave; 
    String[] titelRoute; 
    String[] descRoute; 
    Integer[] bildRoute; 

    ListView listView; 
    List<RowItem> rowItems; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_route_choose); 
     Bundle b = getIntent().getExtras(); 
     if (savedInstanceState != null) { 
       savedInstanceState.getString("stadt"); 
     } 
     else { 
      b.getString("stadt"); 
     } 
      TextView headingRoute = (TextView) findViewById(R.id.routeTitel); 
      headingRoute.setText(String.format(getResources().getString(R.string.route_text)) + " " + b.getString("stadt") + " aus:"); 
      if (b.getString("stadt").equals("Passau")) { 
       titelRoute = new String[]{"Die Altstadt", "Universität", "Essen und Trinken"}; 
       descRoute = new String[]{"Die Altstadt Passaus bietet viele Attraktion: Rathaus, Dom und die vielen kleinen Gassen.", 
         "Deutschlands schönster Campus.", "Kulinarische Köstlichkeiten in Passau"}; 
       bildRoute = new Integer[]{R.drawable.augsburg, R.drawable.bamberg, R.drawable.passau}; 
      } else if (b.getString("stadt").equals("Augsburg")) { 
       titelRoute = new String[]{"Augsburg1", "Augsburg2", "Augsburg3"}; 
       descRoute = new String[]{"Bla bla", "Mehr Bla", "Blubb"}; 
       bildRoute = new Integer[]{R.drawable.augsburg, R.drawable.bamberg, R.drawable.passau}; 
      } else if (b.getString("stadt").equals("Bamberg")) { 
       titelRoute = new String[]{"Bamberg", "Bamberg2", "Bamberg3"}; 
       descRoute = new String[]{"Bla bla", "Mehr Bla", "Blubb"}; 
       bildRoute = new Integer[]{R.drawable.augsburg, R.drawable.bamberg, R.drawable.passau}; 
      } else { 
       try { 
        TextView errorMessage = (TextView) findViewById(R.id.routeTitel); 
        errorMessage.setText(R.string.errorroute); 
       } catch (NullPointerException e) { 
        Context context = getApplicationContext(); 
        CharSequence text = getResources().getString(R.string.errorroute); 
        int duration = Toast.LENGTH_LONG; 
        Toast toast = Toast.makeText(context, text, duration); 
        toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0); 
        toast.show(); 
       } 

      } 

      try { 
       rowItems = new ArrayList<RowItem>(); 
       for (int i = 0; i < titelRoute.length; i++) { 
        RowItem item = new RowItem(bildRoute[i], titelRoute[i], descRoute[i]); 
        rowItems.add(item); 
       } 
       Comparator<RowItem> sortRoutes = new Comparator<RowItem>() { 
        @Override 
        public int compare(RowItem rowItem1, RowItem rowItem2) { 
         return rowItem1.getTitle().compareTo(rowItem2.getTitle()); 
        } 
       }; 
       Collections.sort(rowItems, sortRoutes); 
       listView = (ListView) findViewById(R.id.listRoute); 
       CityListViewAdapter adapter = new CityListViewAdapter(this, R.layout.row_items, rowItems); 
       listView.setAdapter(adapter); 
       listView.setOnItemClickListener(this); 
      } catch (ArrayIndexOutOfBoundsException rowItems) { 
       Context context = getApplicationContext(); 
       CharSequence text = getResources().getString(R.string.ressourcefailed); 
       int duration = Toast.LENGTH_LONG; 
       Toast toast = Toast.makeText(context, text, duration); 
       toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0); 
       toast.show(); 
      } 

    } 

    @Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     Intent intent = new Intent(); 
     intent.setClass(RouteChooseActivity.this, RouteView.class); 
     RowItem item = (RowItem) parent.getItemAtPosition(position); 
     Bundle b = new Bundle(); 
     b.putString("route", item.getTitle().toString()); 
     intent.putExtras(b); 
     startActivity(intent); 
    } 

    protected void onSaveInstanceState(Bundle savedInstanceState) { 
     Bundle b = getIntent().getExtras(); 
     b.getString("stadt"); 
     savedInstanceState.putString("stadt", citySave); 
     super.onSaveInstanceState(savedInstanceState); 
    } 

    @Override 
    public void onRestoreInstanceState(Bundle savedInstanceState) { 
     super.onRestoreInstanceState(savedInstanceState); 
     // Restore UI state from the savedInstanceState. 
     // This bundle has also been passed to onCreate. 
     savedInstanceState.getString(citySave); 
     Log.i("debug", "saved data: " + citySave); 
    } 

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

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     switch (item.getItemId()) { 
      case R.id.action_stadt: 
       setContentView(R.layout.activity_stadt); 
       Intent stadt = new Intent(RouteChooseActivity.this, StadtActivity.class); 
       startActivity(stadt); 
       return true; 
      case R.id.action_help: 
       setContentView(R.layout.activity_help); 
       Intent help = new Intent(RouteChooseActivity.this, Help.class); 
       startActivity(help); 
       return true; 
      case R.id.action_exit: 
       moveTaskToBack(true); 
       System.exit(0); 
       return true; 
      default: 
       return super.onOptionsItemSelected(item); 
     } 
    } 
    } 

답변

0

알아 냈습니다.

당신은 좋은 라이프 사이클 을 얻기 위해 세 가지가 필요합니다 - savedInstanceState 활동이 파괴되는 경우, - onResume, 활동이 다른 응용 프로그램이나 활동 화면이 일시 정지 된 경우, 예를 들어 새를 시작하는 rowItem을 선택하면 활동.내 문제에 대한

는 다음 그것을했다 : 두 번째 활동

protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_route_choose); 
     Bundle b = getIntent().getExtras(); 
     citySave = b.getString("stadt"); 

@Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     Intent intent = new Intent(); 
     intent.setClass(RouteChooseActivity.this, RouteView.class); 
     RowItem item = (RowItem) parent.getItemAtPosition(position); 
     Bundle b = new Bundle(); 
     b.putString("route", item.getTitle().toString()); 
     b.putString("stadt", citySave); 
     intent.putExtras(b); 
     startActivity(intent); 
    } 

    protected void onSaveInstanceState(Bundle savedInstanceState) { 
     super.onSaveInstanceState(savedInstanceState); 
     Bundle b = getIntent().getExtras(); 
     citySave = b.getString("stadt"); 
     savedInstanceState.putString("stadt", citySave); 
    } 

    @Override 
    public void onRestoreInstanceState(Bundle savedInstanceState) { 
     super.onRestoreInstanceState(savedInstanceState); 
     // Restore UI state from the savedInstanceState. 
     // This bundle has also been passed to onCreate. 
     citySave = savedInstanceState.getString("stadt"); 
     Log.i("debug", "saved data: " + citySave); 
    } 

    public void onResume() { 
     super.onResume(); 

      Bundle b = getIntent().getExtras(); 
      citySave = b.getString("stadt"); 

    } 

세 번째 활동

protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_route_view); 
     Bundle b = getIntent().getExtras(); 
     b.getString("route"); 
     citySave = b.getString("stadt"); 

    public void onBackPressed() { 
     super.onBackPressed(); 
     Intent intent = new Intent(); 
     intent.setClass(RouteView.this, RouteChooseActivity.class); 
     Bundle b = new Bundle(); 
     b.putString("stadt", citySave); 
     intent.putExtras(b); 
     startActivity(intent); 
     finish(); 
    } 

    public void onPause() { 
     super.onPause(); 
     Intent intent = new Intent(); 
     intent.setClass(RouteView.this, RouteChooseActivity.class); 
     Bundle b = new Bundle(); 
     b.putString("stadt", citySave); 
     intent.putExtras(b); 
     startActivity(intent); 
     finish(); 
    } 
1

두 가지 오류가 있습니다. 네, 함수를 호출하고 있습니다 만, 실제로는 리턴 값을 사용하고있는 곳이 없습니다.

String myNewString; 
Bundle b = getIntent().getExtras(); 
if (savedInstanceState != null) { 
    myNewString = savedInstanceState.getString("stadt"); 
} else { 
    myNewString = b.getString("stadt"); 
} 

이제 myNewString 대신 b.getString("stadt") 사용합니다.

두 번째로 코드를 onResume 함수에 넣으십시오. 뒤로 버튼을 눌러 두 번째 액티비티로 돌아가려면 onCreate() 함수가 실행되지 않습니다.

2
  1. 는 NullPointerException 올릴 것이다

    :

    savedInstanceState.getString(citySave); 
    Log.i("debug", "saved data: " + citySave); 
    

    그것은해야한다 : onSaveInstanceState에서

    citySave = savedInstanceState.getString("stadt"); 
    Log.i("debug", "saved data: " + citySave); 
    
  2. 당신이 아니면 전멸 될 것이다 (savedInstanceState에 문자열을 추가하기 전에 super.onSaveInstanceState(savedInstanceState);를 호출해야합니다을 ...)

  3. 전체 savedInstanceState은 그 목적에 적합하지 않습니다. Android 수 있습니다 당신이 3 번째 활동에 갈 때 삭제하십시오! (시스템이 메모리를 필요로한다고 생각하면 2 번째 작업과 savedInstanceState가 완전히 없어집니다).

    일을하는 좋은 방법은 의도 된 "여분"번들에 넣은 값으로 2 번째 활동을 시작하려는 의도를 없애기 위해 3 번째 활동의 onBackPressed() 메서드를 무시하는 것입니다.

    이 방법을 사용하면 문제가 해결됩니다.