Dynamic TabHost Crashing in higher version of Android but working fine with 2.3

元气小坏坏 提交于 2019-12-25 09:29:58

问题


I'm building an App which will have a HostTab and will contain two child tabs. I'm not using the .xml for the layout, instead I'm declaring it in the run-time. It is not giving any error during build and was running perfectly in Android 2.3, but in Newer version of Android it is crashing on start. Can anyone help me out in resolving the problem. I'm very new to Android Studio and don't know lot about it.Screen shot when the App is Crashing

My Main Activity (TabExpl.jav) Code is as below:

package com.sanuzr.tabexpl;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
//import android.support.annotation.StringRes;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
//import android.view.ViewDebug;
import android.view.Window;
//import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
//import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ToggleButton;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.TabWidget;
import android.widget.TextView;
import android.widget.Toast;

public class TabExpl extends Activity implements OnClickListener {

//  String                      LOG_TAG                 = "Tab Host Test";
    //-- GUI --//
//  final static String         m_szAppTitle            = "Tab Host Test";
TabHost                     m_tabHost;
ListView                    m_lvSearch; 


public static final int     idBut0      = Menu.FIRST +1,
                            idBut1          = Menu.FIRST +2;

//Tab 1
private View createTabContent1()
{
    final Context cont1 = TabExpl.this;
    // Tab container
    LinearLayout panel = new LinearLayout(cont1);
    panel.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
    panel.setOrientation(LinearLayout.VERTICAL);

    LinearLayout panelH = new LinearLayout(cont1);
    panelH.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
    panelH.setOrientation(LinearLayout.HORIZONTAL);
    //panelH.setGravity(Gravity.LEFT);
    panelH.setGravity(Gravity.CENTER_VERTICAL);
    //Button for searching nearby devices
    Button but = new Button(this);
    //but.setText("Button 1");
    but.setText(getResources().getString(R.string.but_1));
    but.setId(idBut0);
    but.setOnClickListener(this);
    but.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
    panelH.addView(but);
    panel.addView(panelH);

    //Comments below the button
    TextView lbBottom = new TextView(cont1);
    lbBottom.setText(getResources().getString(R.string.msg_1));
    lbBottom.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
    panel.addView(lbBottom);
    return panel;
}

private View createTabContent2()
{
    final Context cont = TabExpl.this;
    // Tab container
    LinearLayout panel = new LinearLayout(cont);
    panel.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
    panel.setOrientation(LinearLayout.VERTICAL);

    //****************************************** Button 1*****************************************
    LinearLayout panelH = new LinearLayout(cont);
    panelH.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
    panelH.setOrientation(LinearLayout.HORIZONTAL);
    //panelH.setGravity(Gravity.CENTER);
    panelH.setGravity(Gravity.CENTER_VERTICAL);

    //Button 1 Text
    TextView tv = new TextView(this);
    tv.setText(getResources().getString(R.string.but_1));
    tv.setLayoutParams(new LayoutParams (LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT, 0.20f));
    tv.setGravity(Gravity.AXIS_PULL_BEFORE);
    panelH.addView(tv);

    //Toggle Button 1
    ToggleButton tb = new ToggleButton(this);
    tb.setTextOn("ON");
    tb.setTextOff("OFF");
    tb.setGravity(Gravity.CENTER);
    tb.setId(idBut1);
    tb.setOnClickListener(this);
    tb.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,0.80f));
    panelH.addView(tb);
    panel.addView(panelH);
    return panel;
}

/**  Main interface: TAB Host **/

private View createMainTABHost() {
    // construct the TAB Host
    TabHost tabHost = new TabHost(this);
    tabHost.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

    // the tabhost needs a tabwidget, that is a container for the visible tabs
    TabWidget tabWidget = new TabWidget(this);
    tabWidget.setId(android.R.id.tabs);
    tabHost.addView(tabWidget, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

    // the tabhost needs a frame layout for the views associated with each visible tab
    FrameLayout frameLayout = new FrameLayout(this);
    frameLayout.setId(android.R.id.tabcontent);
    frameLayout.setPadding(0, 65, 0, 0);
    tabHost.addView(frameLayout, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

    // setup must be called if you are not initialising the tabhost from XML
    tabHost.setup(); 

    // create the tabs
    TabSpec ts1, ts2;

    ts1 = tabHost.newTabSpec("TAB_TAG_1");
    ts1.setIndicator(getResources().getString(R.string.msg_2));
    ts1.setContent(new TabHost.TabContentFactory(){
        public View createTabContent(String tag)
        {
            return createTabContent2();
        }
    });
    tabHost.addTab(ts1);

    ts2 = tabHost.newTabSpec("TAB_TAG_2");
    ts2.setIndicator(getResources().getString(R.string.msg_3));
    ts2.setContent(new TabHost.TabContentFactory(){
        public View createTabContent(String tag)
        {
            return createTabContent1();
        }
    });

    tabHost.addTab(ts2);

    return tabHost;
}

 /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    // disable the titlebar
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    // create the interface
    m_tabHost = (TabHost)createMainTABHost();

    setContentView(m_tabHost);
}
// The BroadcastReceiver that listens for discovered devices and
// changes the title when discovery is finished

@Override
public void onClick(View v) {
    int cmdId = v.getId();
    Toast toast;
    //If Button 0 is Toggled
    if (cmdId == idBut0)
    {
        toast = Toast.makeText(this, "Button Clicked", Toast.LENGTH_LONG);
        toast.setGravity(Gravity.TOP, 25, 400);
        toast.show();
    }

    //If Button 1 is Toggled

    if (cmdId == idBut1)
    {

        boolean on = ((ToggleButton) v).isChecked();

        if (on) {

            toast = Toast.makeText(this, "Toggle Switch Activated", Toast.LENGTH_LONG);
            toast.setGravity(Gravity.TOP, 25, 400);
            toast.show();
        } else {

            toast = Toast.makeText(this, "Toggle Switch De-activated", Toast.LENGTH_LONG);
            toast.setGravity(Gravity.TOP, 25, 400);
            toast.show();
        }

    }


}

}

The string.xml contains the below code

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Tab Example</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="but_1">Button 1</string>
    <string name="msg_1">Tap on the button to Test.</string>
    <string name="msg_2">Tab 1</string>
    <string name="msg_3">Tab 2</string>

</resources>

and the build.gradle looks like below

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "25.0.2"

    defaultConfig {
        applicationId "com.sanuzr.tabexpl"
        minSdkVersion 22
        targetSdkVersion 22
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    //compile 'com.android.support:support-v4:18.0.0'
    compile 'com.android.support:appcompat-v7:22.1.0'
}

Here is the crash report. Please note, the package name of the crash report and the code is different:

    05-27 00:10:11.000 3506-6398/? I/ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=nr.co.btremote/.BTRemote bnds=[540,870][804,1167] (has extras)} from uid 10019 on display 0
05-27 00:10:11.059 3506-4537/? I/ActivityManager: Start proc 16710:nr.co.btremote/u0a136 for activity nr.co.btremote/.BTRemote
05-27 00:10:11.195 16710-16710/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: nr.co.btremote, PID: 16710
                                                   java.lang.RuntimeException: Unable to start activity ComponentInfo{nr.co.btremote/nr.co.btremote.BTRemote}: android.content.res.Resources$NotFoundException: Resource ID #0x0
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                                                       at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                       at android.os.Looper.loop(Looper.java:154)
                                                       at android.app.ActivityThread.main(ActivityThread.java:6077)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
                                                    Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x0
                                                       at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:190)
                                                       at android.content.res.Resources.loadXmlResourceParser(Resources.java:2107)
                                                       at android.content.res.Resources.getLayout(Resources.java:1124)
                                                       at android.view.LayoutInflater.inflate(LayoutInflater.java:424)
                                                       at android.widget.TabHost$LabelIndicatorStrategy.createIndicatorView(TabHost.java:573)
                                                       at android.widget.TabHost.addTab(TabHost.java:209)
                                                       at nr.co.btremote.BTRemote.createMainTABHost(BTRemote.java:139)
                                                       at nr.co.btremote.BTRemote.onCreate(BTRemote.java:164)
                                                       at android.app.Activity.performCreate(Activity.java:6705)
                                                       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
                                                       at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                       at android.os.Looper.loop(Looper.java:154) 
                                                       at android.app.ActivityThread.main(ActivityThread.java:6077) 
                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
05-27 00:10:11.197 3506-11957/? W/ActivityManager:   Force finishing activity nr.co.btremote/.BTRemote
05-27 00:10:11.701 3506-3600/? W/ActivityManager: Activity pause timeout for ActivityRecord{f90f7bd u0 nr.co.btremote/.BTRemote t2631 f}
05-27 00:10:11.728 3506-3600/? I/WindowManager: Failed to capture screenshot of Token{56341b2 ActivityRecord{f90f7bd u0 nr.co.btremote/.BTRemote t2631 f}} appWin=Window{28ffb98 u0 Starting nr.co.btremote} drawState=4
05-27 00:10:22.040 3506-3600/? W/ActivityManager: Activity destroy timeout for ActivityRecord{f90f7bd u0 nr.co.btremote/.BTRemote t2631 f}

Further,to get the exact problem, I copied all the view items of createTabContent1() into the createMainTABHost() and added the view into it. This is not crashing now and it's running smoothly. Hence, I could make out that there is no problem in the child tabs createTabContent1()/ createTabContent2() and also createMainTABHost() is fine. But there is some problem in invoking the TabSpec from createMainTABHost() by the TabHost.TabContentFactory() method. Hope, this will give a better clue about the problem.

private View createMainTABHost() {
        // construct the TAB Host
        TabHost tabHost = new TabHost(this);
        tabHost.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

        // the tabhost needs a tabwidget, that is a container for the visible tabs
        TabWidget tabWidget = new TabWidget(this);
        tabWidget.setId(android.R.id.tabs);
        tabHost.addView(tabWidget, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

        // the tabhost needs a frame layout for the views associated with each visible tab
        FrameLayout frameLayout = new FrameLayout(this);
        frameLayout.setId(android.R.id.tabcontent);
        frameLayout.setPadding(0, 65, 0, 0);
        tabHost.addView(frameLayout, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

        // setup must be called if you are not initialising the tabhost from XML
        tabHost.setup(); 

        // create the tabs
        TabSpec ts1, ts2;

        ts1 = tabHost.newTabSpec("TAB_TAG_1");
        ts1.setIndicator(getResources().getString(R.string.msg_2));
        ts1.setContent(new TabHost.TabContentFactory(){
            public View createTabContent(String tag)
            {
                return createTabContent1();
            }
        });
        //tabHost.addTab(ts1);

        ts2 = tabHost.newTabSpec("TAB_TAG_2");
        ts2.setIndicator(getResources().getString(R.string.msg_3));
        ts2.setContent(new TabHost.TabContentFactory(){
            public View createTabContent(String tag)
            {
                return createTabContent2();
            }
        });

        //tabHost.addTab(ts2);

        LinearLayout panel = new LinearLayout(this);
        panel.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
        panel.setOrientation(LinearLayout.VERTICAL);

        //****************************************** Button 1*****************************************
        LinearLayout panelH = new LinearLayout(this);
        panelH.setLayoutParams(new 

    LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
            panelH.setOrientation(LinearLayout.HORIZONTAL);
            //panelH.setGravity(Gravity.CENTER);
            panelH.setGravity(Gravity.CENTER_VERTICAL);

            //Button 1 Text
            TextView tv = new TextView(this);
            tv.setText(getResources().getString(R.string.but_1));
            tv.setLayoutParams(new LayoutParams (LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT, 0.20f));
            tv.setGravity(Gravity.AXIS_PULL_BEFORE);
            panelH.addView(tv);

            //Toggle Button 1
            ToggleButton tb = new ToggleButton(this);
            tb.setTextOn("ON");
            tb.setTextOff("OFF");
            tb.setGravity(Gravity.CENTER);
            tb.setId(idBut1);
            tb.setOnClickListener(this);
            tb.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,0.80f));
            panelH.addView(tb);
            panel.addView(panelH);


            tabHost.addView(panel);


            return tabHost;
        }

A Screen Shot after this:When the content of the Tab is put in the TabHost

来源:https://stackoverflow.com/questions/44200150/dynamic-tabhost-crashing-in-higher-version-of-android-but-working-fine-with-2-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!