问题
Ok, I was working on a Android app that can show you a few things like TV schedule, News, Wather Forecast and Horoscope using RSS. The app works as it should on Android 2.1 or 2.3.X, but when I start it on 4.0 or 4.1 it stops working after I chose any option from main.
The structure of app is:
-Main
-Activity for specific thing (like just News) that has a view
-XML Parser class that is called by previous class
-Activity for Signle View (like just one information from whole bunch of news) with it's view
Here I provide the Manifest, Log and few classes:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mtel.vodic"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="14" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".Vodic"
android:label="@string/title_activity_pocetna" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Pomoc"
android:label="@string/m_tel_vodi_za_odlu_ne"
></activity>
<activity
android:name=".Pomocna"
android:label="@string/m_tel_vodi_za_odlu_ne"
></activity>
<activity
android:name=".SingleMenuItemActivity"
android:label="@string/m_tel_vodi_za_odlu_ne"
></activity>
.
.
.
</application>
<uses-permission android:name="android.permission.INTERNET" />
<!-- Needed to check when the network connection changes -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
</manifest>
Error Log:
10-18 20:35:05.457: E/Trace(730): error opening trace file: No such file or directory (2)
10-18 20:35:06.197: I/Choreographer(730): Skipped 30 frames! The application may be doing too much work on its main thread.
10-18 20:35:06.257: D/gralloc_goldfish(730): Emulator without GPU emulation detected.
10-18 20:35:11.316: D/AndroidRuntime(730): Shutting down VM
10-18 20:35:11.316: W/dalvikvm(730): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
10-18 20:35:11.347: E/AndroidRuntime(730): FATAL EXCEPTION: main
10-18 20:35:11.347: E/AndroidRuntime(730): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mtel.vodic/com.mtel.vodic.Vijesti}: java.lang.NullPointerException
10-18 20:35:11.347: E/AndroidRuntime(730): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
10-18 20:35:11.347: E/AndroidRuntime(730): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
10-18 20:35:11.347: E/AndroidRuntime(730): at android.app.ActivityThread.access$600(ActivityThread.java:130)
10-18 20:35:11.347: E/AndroidRuntime(730): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
10-18 20:35:11.347: E/AndroidRuntime(730): at android.os.Handler.dispatchMessage(Handler.java:99)
10-18 20:35:11.347: E/AndroidRuntime(730): at android.os.Looper.loop(Looper.java:137)
10-18 20:35:11.347: E/AndroidRuntime(730): at android.app.ActivityThread.main(ActivityThread.java:4745)
10-18 20:35:11.347: E/AndroidRuntime(730): at java.lang.reflect.Method.invokeNative(Native Method)
10-18 20:35:11.347: E/AndroidRuntime(730): at java.lang.reflect.Method.invoke(Method.java:511)
10-18 20:35:11.347: E/AndroidRuntime(730): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
10-18 20:35:11.347: E/AndroidRuntime(730): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-18 20:35:11.347: E/AndroidRuntime(730): at dalvik.system.NativeStart.main(Native Method)
10-18 20:35:11.347: E/AndroidRuntime(730): Caused by: java.lang.NullPointerException
10-18 20:35:11.347: E/AndroidRuntime(730): at com.mtel.vodic.Vijesti.onCreate(Vijesti.java:61)
10-18 20:35:11.347: E/AndroidRuntime(730): at android.app.Activity.performCreate(Activity.java:5008)
10-18 20:35:11.347: E/AndroidRuntime(730): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
10-18 20:35:11.347: E/AndroidRuntime(730): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
10-18 20:35:11.347: E/AndroidRuntime(730): ... 11 more
10-18 20:35:13.926: I/Process(730): Sending signal. PID: 730 SIG: 9
Main:
public class Vodic extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pocetna);
Button tv = (Button)findViewById(R.id.tv);
Button vijesti = (Button)findViewById(R.id.vijesti);
Button horoskop = (Button)findViewById(R.id.horoskop);
Button vremenska_prognoza = (Button)findViewById(R.id.vremenska_prognoza);
Button o_aplikaciji = (Button)findViewById(R.id.o_aplikaciji);
Button pomoc = (Button)findViewById(R.id.pomoc);
.
.
.
vijesti.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent xw = new Intent(getApplicationContext(), Vijesti.class );
//xw.putExtra("A", "http://bih-x.info/feed/");
xw.putExtra("A", "http://klix.ba/rss/naslovnica");
if(!isOnline()) {
Toast.makeText(getApplicationContext(), "Niste povezani sa internetom!", Toast.LENGTH_SHORT).show();
} else {
startActivity(xw);
}
}
});
.
.
.
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if(netInfo != null && netInfo.isConnected()) {
return true;
}
return false;
}
}
Activity:
public class Vijesti extends ListActivity {
static String url =null;
// XML node keys
static final String KEY_ITEM = "item"; // parent node
static final String KEY_TITLE = "title";
static final String KEY_DATE = "pubDate";
static final String KEY_DESC = "encoded";
static final String UVOD = "uvod";
static final String CLANAK = "clanak";
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.vijesti_m);
Intent in = getIntent();
// Get XML values from previous intent
url = in.getStringExtra("A");
final ArrayList<HashMap<String,String>> menuItems = new ArrayList<HashMap<String,String>>();
ArrayList<String> xqw = new ArrayList<String>();
ParserVijesti parser=null;
Document doc=null;
try {
parser = new ParserVijesti();
String xml = parser.getXmlFromUrl(url); //get XML
doc = parser.getDomElement(xml);
} catch (Exception e1) {
finish();
}
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
//loop
for (int i=0; i< nl.getLength(); i++){
HashMap<String, String> map = new HashMap<String, String>();
HashMap<String, String> mapq = new HashMap<String, String>();
Element e = (Element) nl.item(i);
//add to map
map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
map.put(KEY_DATE, parser.getValue(e, KEY_DATE));
map.put(UVOD, parser.getValue(e,UVOD));
map.put(CLANAK, parser.getValue(e,CLANAK));
menuItems.add(map);
xqw.add(parser.getValue(e,KEY_TITLE));
}
for(int gf=0; gf<xqw.size(); gf++){
Log.w("ISPISI: ", xqw.get(gf));
}
ArrayAdapter adapterx = new ArrayAdapter(this, R.layout.vijesti_m,R.id.tetkica, xqw);
setListAdapter(adapterx);
//singleView
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
int hg = position;
HashMap<String, String> kaktus = menuItems.get(hg);
String uvod1 = kaktus.get(UVOD);
String clanak1 = kaktus.get(CLANAK);
String dat1 = kaktus.get(KEY_DATE);
String tit1 = kaktus.get(KEY_TITLE);
//intent
Intent inx = new Intent(getApplicationContext(), VijestiSingle.class);
inx.putExtra(KEY_TITLE, tit1);
inx.putExtra(KEY_DATE, dat1);
inx.putExtra(UVOD, uvod1);
inx.putExtra(CLANAK, clanak1);
startActivity(inx);
}
});
}
}
XML Parsing Class:
public class ParserVijesti {
// constructor
public ParserVijesti() {
}
/**
* Getting XML from URL making HTTP request
* @param url string
* */
public String getXmlFromUrl(String url) {
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// return XML
return xml;
}
/**
* Getting XML DOM element
* @param XML string
* */
public Document getDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setCoalescing(true);
dbf.setNamespaceAware(true);
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setByteStream(new ByteArrayInputStream(xml.getBytes("UTF-8")));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
return doc;
}
/** Getting node value
* @param elem element
*/
public final String getElementValue( Node elem ) {
Node child;
if( elem != null){
if (elem.hasChildNodes()){
for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
if(child.getNodeType() == Node.TEXT_NODE || child.getNodeType() == Node.CDATA_SECTION_NODE){
return child.getNodeValue();
}
}
}
}
return "";
}
public final String getElementValue2( Node elem ) {
Node child;
if( elem != null){
if (elem.hasChildNodes()){
for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
if(child.getNodeType() == Node.CDATA_SECTION_NODE){
return child.getNodeValue();
}
}
}
}
return "SRANJE";
}
/**
* Getting node value
* @param Element node
* @param key string
* */
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
public String getValue3(Element item, String str){
NodeList n = item.getElementsByTagNameNS("http://purl.org/rss/1.0/modules/content/", str);
String ses = this.getElementValue2(n.item(0));
//String mim =ses.replaceAll("(?s)\\<.*?\\>", " \n");
String html = ses;
Spanned strxa = Html.fromHtml(html);
String fffx=strxa.toString();
//return this.getElementValue2(n.item(0));
//return ses;
//return Promjena(ses);
return fffx;
}
}
To sum up: App works as it should on 2.1 or 2.3.x but stops after I chose anything from main activity on Android 4.0 or 4.1. I don't know what's up with it.. can anybody help?
回答1:
According to the logs, you're getting a null pointer on Vijesti.java:61
. You said this line is:
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
That means doc
must be null. Since you assign that with getDomElement()
, it means your problem lies in that method. The only way I see that it could be null (since DocumentBuilder.parse()
can't return null) is if you're hitting one of your catch
statements.
Do you get any of the catch
exception messages in your logcat? The portion you've shown only lists the actual errors resulting from the null pointer. Your message would probably be a bit before that. Check for that, and you'll be able to tell which exception you're getting, and handle it accordingly.
回答2:
This will not solve your original problem, but:
I think this is another problem you are having: You are publishing your app with a targetSdkVersion higher than you have tested and confirmed your application to work against.
You have set the targetSdkVersion to 14. But if you read this:
Android Min SDK Version vs. Target SDK Version
you will understand that setting targetSdkVersion to 14 means that you are telling Android "I have tested my app on API 14 and confirm that it is working, please disable all compatibility settings for versions lower than API 14".
But this is not true, you have actually confirmed the opposite, that the app is NOT working on 4.0!
If you set targetSdkVersion to 14 it will make Android 4.0 disable compatibility settings it normally uses to ensure that apps for older APIs work (f.i. GPU rendering, JNI changes)
So for now you should just set minSdkVersion and no targetSdkVersion when you publish your app, to keep the compatibility behaviors enabled in 4.0.
Raise targetSdkVersion to 14 only after you have fixed the original bug and tested your app on against API 14, and not before.
来源:https://stackoverflow.com/questions/12963646/android-app-cant-start-on-android-4-0