问题
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