我正在构建一个具有HostTab的应用程序,它将包含两个子选项卡。我没有使用.xml作为布局,而是在运行时声明它。它在构建期间没有给出任何错误,并且在Android 2.3中运行得很好,但在较新版本的Android中,它在启动时崩溃。任何人都可以帮助我解决问题。我是Android Studio的新手,对此并不了解。Screen shot when the App is Crashing
我的主要活动(TabExpl.jav)代码如下:
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();
}
}
}
}
string.xml包含以下代码
<?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>
,build.gradle如下所示
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'
}
这是崩溃报告。请注意,崩溃报告的包名称和代码是不同的:
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}
此外,为了解决确切的问题,我将createTabContent1()的所有视图项复制到createMainTABHost()中并将视图添加到其中。这不会崩溃,而且运行顺畅。因此,我可以看出子选项卡createTabContent1()/ createTabContent2()和createMainTABHost()都没有问题。但是通过TabHost.TabContentFactory()方法从createMainTABHost()调用TabSpec存在一些问题。希望,这将为这个问题提供更好的线索。
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;
}