簡體   English   中英

Android應用程序因方向更改而崩潰

[英]Android application crashes with orientation change

該應用程序有一個主要活動和兩個片段。 主活動主機MainFragmentMainFragment包含一個提交BreedingFragment (運行)的按鈕。 僅當方向未更改時應用程序才能正常工作,但在BreedingFragment打開且方向更改時崩潰。

在對stackoverflow進行了幾個小時的調查之后,我找到了以下文章並按照答案進行了調查,但它沒有調試問題。

  1. Android應用程序因方向更改而崩潰
  2. 方向更改崩潰應用程序
  3. 旋轉屏幕崩潰Android應用程序
  4. 當我更改屏幕方向時,我的Android應用程序崩潰了

答案主要建議在AndroidManifest.xml使用以下代碼:

android:configChanges="orientation|keyboardHidden|screenSize"

最后一個帖子建議考慮以下內容:

每次設備方向更改時,活動實際上會停止並重新啟動。 你需要記住你的線程,即停止線程並在設備改變方向時重新啟動它,也許在兩者之間保存狀態。

主要活動:

public class MainActivity extends FragmentActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

MainFragment:

public class MainFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_main, container, false);

        Button breedButton = (Button) v.findViewById(R.id.pokemon_breeding_button);

        breedButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                final FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.fragment, new BreedingFragment());
                transaction.addToBackStack(null);
                transaction.commit();
            }
        });
        return v;
    }
}

BreedingFragment:

public class BreedingFragment extends Fragment {

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_breeding, container, false);
    }
}

Log Cat:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.revittechnology.zapdos, PID: 12795
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.revittechnology.zapdos/com.revittechnology.zapdos.MainActivity}: android.view.InflateException: Binary XML file line #24: Error inflating class fragment
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2429)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493)
                      at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4014)
                      at android.app.ActivityThread.access$900(ActivityThread.java:166)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:136)
                      at android.app.ActivityThread.main(ActivityThread.java:5590)
                      at java.lang.reflect.Method.invokeNative(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:515)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1280)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1096)
                      at dalvik.system.NativeStart.main(Native Method)
                   Caused by: android.view.InflateException: Binary XML file line #24: Error inflating class fragment
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:720)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:762)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:771)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:771)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:499)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
                      at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:331)
                      at android.app.Activity.setContentView(Activity.java:2018)
                      at com.revittechnology.zapdos.MainActivity.onCreate(MainActivity.java:13)
                      at android.app.Activity.performCreate(Activity.java:5447)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2393)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493) 
                      at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4014) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:166) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:136) 
                      at android.app.ActivityThread.main(ActivityThread.java:5590) 
                      at java.lang.reflect.Method.invokeNative(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:515) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1280) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1096) 
                      at dalvik.system.NativeStart.main(Native Method) 
                   Caused by: java.lang.IllegalStateException: Fragment com.revittechnology.zapdos.MainFragment did not create a view.
                      at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2319)
                      at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:120)
                      at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:356)
                      at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31)
                      at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:79)
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:762) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:771) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:771) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:499) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:398) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:354) 
                      at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:331) 
                      at android.app.Activity.setContentView(Activity.java:2018) 
                      at com.revittechnology.zapdos.MainActivity.onCreate(MainActivity.java:13) 
                      at android.app.Activity.performCreate(Activity.java:5447) 
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094) 
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2393) 
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493) 
                      at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4014) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:166) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:136) 
                      at android.app.ActivityThread.main(ActivityThread.java:5590) 
                      at java.lang.reflect.Method.invokeNative(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:515) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1280) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1096) 
                      at dalvik.system.NativeStart.main(Native Method) 
I/Process: Sending signal. PID: 12795 SIG: 9
Application terminated.

主要活動和主要片段。 上面的照片詳細說明了這個案例。 承載MainFragment.java和Main Fragment的MainActivity.java有一個按鈕,用於啟動另一個片段。

我的要求是什么?

  1. 主活動只承載主片段,沒有任何其他內容。
  2. Main Fragment有按鈕來啟動第二個片段。
  3. 按下后退按鈕時關閉(結束/完成)第二個片段(返回主活動)。
  4. 與設備(屏幕)旋轉一起使用。

第一步是創建主要活動。 主要活動中有幾件事需要考慮

  1. MainActivity擴展為FragmentActivity

public class MainActivity extends FragmentActivity ,如下所示:

  1. 檢查savedInstanceState ,如果為null則運行MainFragment。 我們這樣做是為了避免一次又一次地使用設備輪換運行MainFragment。

以下是MainActivity.java的代碼:

public class MainActivity extends FragmentActivity {

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

        if (savedInstanceState == null) {
            FragmentManager fManager = getSupportFragmentManager();
            FragmentTransaction fTransaction = fManager.beginTransaction();
            fTransaction.add(R.id.fragment, new MainFragment());
            fTransaction.commit();
        }

    }
}

確保在activity_main.xml有以下代碼行:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.revittechnology.zapdos.MainFragment"
    android:id="@+id/fragment" /> 

現在創建MainFragment.java

public class MainFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_main, container, false);
        // Inflate the layout for this fragment
        Button breedButton = (Button) v.findViewById(R.id.pokemon_breeding_button);

        breedButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                final FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.fragment, new BreedingFragment());
                transaction.addToBackStack("tag");
                transaction.commit();
            }
        });
        return v;
    }
}

在返回視圖( return v )之前包括所有代碼,因為如果視圖不存在,則無法找到按鈕和布局的其他元素。 transaction.addToBackStack("tag"); 有助於將片段添加到后台堆棧中,並允許返回以通過反壓來關閉片段。

現在創建第二個片段BreedingFragment.java`

public class BreedingFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_breeding, container, false);
    }
}

注意:在聲明類之前,請導入上述類所需的庫。

結論:應用程序因設備方向而崩潰,因為第二個片段是通過按鈕單擊啟動的,MainFragment是MainActivity的主機。 使用設備方向時,Fragments已關閉, MainActivity.java中沒有代碼可以再次啟動碎片,因此,它提供了空的異常錯誤。 將片段相關代碼添加到MainActivity.java以啟動片段以編程方式解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM