2014-11-04 65 views
0

我正在做一個簡單的android編程培訓。 我的應用程序擁有一個ArrayList的人。 點擊「get count」,爲結果開始一個新的活動,當用戶返回主活動時,它應該顯示新片段中的人數。 問題是,當FragmentManager添加片段(在.commit行中)時,應用程序崩潰。 這是我的代碼:程序崩潰後通過插入一個新的片段從活動返回

mainActivity:

package com.example.myapp; 

    import java.util.ArrayList; 
    import java.util.Hashtable; 

    import android.support.v4.app.Fragment; 
    import android.support.v7.app.ActionBarActivity; 
    import android.support.v4.app.FragmentManager; 
    import android.content.Intent; 
    import android.os.Bundle; 
    import android.view.Menu; 
    import android.view.MenuItem; 
    import android.view.View; 
    import android.widget.ArrayAdapter; 
    import android.widget.Button; 
    import android.widget.EditText; 
    import android.widget.ListView; 
    import android.widget.TextView; 
    import android.view.View.OnClickListener; 

    public class MainActivity extends ActionBarActivity { 

     private final int GET_COUNT = 0; 
     private Button mAddButton; 
     private Button mAddPictureButton; 
     private EditText mFirstName; 
     private EditText mLastName; 
     private EditText mId; 

     private ListView listView; 

     protected ArrayList<Person> mPersonList; 
     protected ArrayAdapter<Person> mAdapter; 


     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 
      listView = (ListView) findViewById(R.id.listView); 
      if (mPersonList == null){ 
       mPersonList = new ArrayList<Person>(); 
      } 

      if (mAdapter == null){ 
       mAdapter = new ArrayAdapter<Person>(this, 
         android.R.layout.simple_list_item_1, 
         mPersonList); 
       listView.setAdapter(mAdapter); 
      } 

      mAddButton = (Button) findViewById(R.id.add); 
      mAddButton.setOnClickListener(new OnClickListener() { 
        public void onClick(View v) { 
         mId = (EditText) findViewById(R.id.id); 
         mFirstName = (EditText) findViewById(R.id.firstName); 
         mLastName = (EditText) findViewById(R.id.lastName); 

         Person p1 = new Person(Integer.parseInt(mId.getText().toString()), 
           mFirstName.getText().toString(), 
           mLastName.getText().toString()); 
         mPersonList.add(p1); 
         mAdapter.notifyDataSetChanged(); 
         mId.setText(""); 
         mFirstName.setText(""); 
         mLastName.setText(""); 
        } 
       }); 

      mAddPictureButton = (Button) findViewById(R.id.getCount); 
      mAddPictureButton.setOnClickListener(new OnClickListener() { 
        public void onClick(View v) { 

         Intent intent = new Intent(MainActivity.this, GetCount.class); 
         intent.putExtra("personList", mPersonList); 
         startActivityForResult(intent, GET_COUNT); 
        } 
       }); 
     } 

     @Override 
     protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
      // Check which request we're responding to 
      if (requestCode == GET_COUNT) { 

       FragmentManager fm = getSupportFragmentManager(); 
       Fragment fragment = fm.findFragmentById(R.id.fragmentContainer); 
       if (fragment == null) { 
       fragment = new BlankFragment(); 
       fm.beginTransaction() 
       .add(R.id.fragmentContainer, fragment) 
       .commit(); 
       } 
       TextView tv= (TextView) findViewById(R.id.count); 
       int count = data.getIntExtra("count", 0); 
       tv.setText("" + count); 
      } 
     } 

     @Override 
     public boolean onCreateOptionsMenu(Menu menu) { 
      // Inflate the menu; this adds items to the action bar if it is present. 
      getMenuInflater().inflate(R.menu.main, 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. 
      int id = item.getItemId(); 
      if (id == R.id.action_settings) { 
       return true; 
      } 
      return super.onOptionsItemSelected(item); 
     } 
    } 

mainActivity佈局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 
    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" > 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/firstName" /> 

     <EditText android:id="@+id/firstName" 
      android:layout_width="50dp" 
      android:inputType="text" 
      android:hint ="" 
      android:layout_height="wrap_content" /> 

    </LinearLayout> 
    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" > 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/lastName" /> 

     <EditText android:id="@+id/lastName" 
      android:layout_width="50dp" 
      android:inputType="text" 
      android:hint ="" 
      android:layout_height="wrap_content" /> 

    </LinearLayout> 
    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" > 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/id" /> 

     <EditText android:id="@+id/id" 
      android:layout_width="50dp" 
      android:inputType="text" 
      android:hint ="" 
      android:layout_height="wrap_content" /> 

    </LinearLayout> 
    <Button 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/getCount" 
      android:id="@+id/getCount"/> 

    <FrameLayout 
     android:id="@+id/fragmentContainer" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
    /> 

    <Button 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/add" 
      android:id="@+id/add"/> 
    <ListView 
       android:id="@+id/listView" 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content"/> 

</LinearLayout> 

GetCountActivity:

package com.example.myapp; 

import java.util.ArrayList; 

import android.support.v7.app.ActionBarActivity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 

public class GetCount extends ActionBarActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_get_count); 
    @SuppressWarnings("unchecked") 
    ArrayList<Person> persons = (ArrayList<Person>) getIntent().getSerializableExtra("personList"); 
    int count = 0; 
    for (@SuppressWarnings("unused") Person person : persons) 
    { 
     count++; 
    } 
    Intent data = new Intent(); 
    data.putExtra("count", count); 
    setResult(RESULT_OK, data); 
} 

} 

getCount將佈局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:paddingBottom="@dimen/activity_vertical_margin" 
     android:paddingLeft="@dimen/activity_horizontal_margin" 
     android:paddingRight="@dimen/activity_horizontal_margin" 
     android:paddingTop="@dimen/activity_vertical_margin" 
     tools:context="com.example.myapp.GetCount" > 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="@string/counting" /> 

    </RelativeLayout> 

countFragment:

package com.example.myapp; 


import android.app.Activity; 
import android.net.Uri; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

/** 
* A simple {@link Fragment} subclass. Activities that contain this fragment 
* must implement the {@link CountFragment.OnFragmentInteractionListener} 
* interface to handle interaction events. Use the 
* {@link CountFragment#newInstance} factory method to create an instance of 
* this fragment. 
* 
*/ 
public class CountFragment extends Fragment { 



    public static CountFragment newInstance(String param1, String param2) { 
     CountFragment fragment = new CountFragment(); 
     Bundle args = new Bundle(); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    public CountFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 
     return inflater.inflate(R.layout.fragment_blank, container, false); 
    } 

} 

片段佈局:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     tools:context="com.example.myapp.CountFragment" > 

     <!-- TODO: Update blank fragment layout --> 

     <TextView 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:text="" 
       android:id="@+id/count" /> 

    </FrameLayout> 

人:

package com.example.myapp; 

public class Person implements java.io.Serializable{ 
    private int id; 
    private String firstName; 
    private String lastName; 

    public Person(){} 

    public Person(int id, String firstName, String lastName){ 
     this.id = id; 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    @Override 
    public String toString() { 
     return "Person [id=" + id + ", firstName=" + firstName + ", lastName=" 
       + lastName + "]"; 
    } 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 


} 

logcat的:

11-04 04:34:10.082: D/libEGL(4656): loaded /system/lib/egl/libEGL_genymotion.so 
11-04 04:34:10.082: D/(4656): HostConnection::get() New Host Connection established 0xb7f189f8, tid 4656 
11-04 04:34:10.110: D/libEGL(4656): loaded /system/lib/egl/libGLESv1_CM_genymotion.so 
11-04 04:34:10.114: D/libEGL(4656): loaded /system/lib/egl/libGLESv2_genymotion.so 
11-04 04:34:10.222: W/EGL_genymotion(4656): eglSurfaceAttrib not implemented 
11-04 04:34:10.222: E/OpenGLRenderer(4656): Getting MAX_TEXTURE_SIZE from GradienCache 
11-04 04:34:10.230: E/OpenGLRenderer(4656): Getting MAX_TEXTURE_SIZE from Caches::initConstraints() 
11-04 04:34:10.230: D/OpenGLRenderer(4656): Enabling debug mode 0 
11-04 04:34:39.834: W/EGL_genymotion(4656): eglSurfaceAttrib not implemented 
11-04 04:34:41.242: D/AndroidRuntime(4656): Shutting down VM 
11-04 04:34:41.242: W/dalvikvm(4656): threadid=1: thread exiting with uncaught exception (group=0xa4c1b648) 
11-04 04:34:41.246: E/AndroidRuntime(4656): FATAL EXCEPTION: main 
11-04 04:34:41.246: E/AndroidRuntime(4656): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { (has extras) }} to activity {com.example.myapp/com.example.myapp.MainActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.app.ActivityThread.deliverResults(ActivityThread.java:3367) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.app.ActivityThread.handleSendResult(ActivityThread.java:3410) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.app.ActivityThread.access$1100(ActivityThread.java:141) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1304) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.os.Handler.dispatchMessage(Handler.java:99) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.os.Looper.loop(Looper.java:137) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.app.ActivityThread.main(ActivityThread.java:5103) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at java.lang.reflect.Method.invokeNative(Native Method) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at java.lang.reflect.Method.invoke(Method.java:525) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at dalvik.system.NativeStart.main(Native Method) 
11-04 04:34:41.246: E/AndroidRuntime(4656): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1360) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1378) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at com.example.myapp.MainActivity.onActivityResult(MainActivity.java:92) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.app.Activity.dispatchActivityResult(Activity.java:5322) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  at android.app.ActivityThread.deliverResults(ActivityThread.java:3363) 
11-04 04:34:41.246: E/AndroidRuntime(4656):  ... 11 more 

回答

1

編輯: 閱讀這篇文章:IllegalStateException: onSaveInstanceState崩潰

檢查:

if (requestCode == GET_COUNT) { 
    if (resultCode == RESULT_OK) { // add this check 
    // then proceed to whatever you want to do 
    } 
} 

同時,確保

TextView tv= (TextView) findViewById(R.id.count); 

存在,即BlankFragment片段是完全充氣和可使用前它。

最後但並非最不重要的,我認爲,您將不得不在Framelayout部分有一個<fragment ... />部分 - 但我不確定這部分。

<FrameLayout 
    android:id="@+id/fragmentContainer" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
/> 
+0

我做了你的兩個第一個建議,但它仍然是crasing。如果您將片段佈局放入部分中,片段將是靜態的(您不能替換它),並且不需要使用fragmentManager進行插入。 – 2014-11-04 03:30:58

+0

是否仍然與您在OP中發佈的日誌相同? – 2014-11-04 03:34:50

+0

如果是,那麼我已經編輯了一篇文章的鏈接,解釋了爲什麼你會看到這個異常以及如何解決它。 – 2014-11-04 03:40:53