我的应用程序有问题,这是一个获取新闻源的应用程序,此应用程序有一个小部件,通过添加到xml文件的最新消息的数量显示通知。
在api 8级上,每个东西都没关系,并且小部件工作正常,但是当我将eclipse的版本和api级别更改为api级别17时,小部件停止了!!我有例外!!
以下是我用来更新小部件的两个类:
1)MyWidgetProvider类:
package com.example.testfeeds;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import java.util.Random;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
public class MyWidgetProvider extends AppWidgetProvider {
private static final String LOG = "testwidgets";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Log.w(LOG, "onUpdate method called");
// Get all ids
ComponentName thisWidget = new ComponentName(context,
MyWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
// Build the intent to call the service
Intent intent = new Intent(context.getApplicationContext(),
UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
// Update the widgets via the service
context.startService(intent);
}
}
2)UpdateWidgetService:
package com.example.testfeeds;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.IBinder;
import android.util.Log;
import android.webkit.WebView.FindListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RemoteViews;
import android.widget.TextView;
public class UpdateWidgetService extends Service {
public static int numberOfItems=0;
//numberOfItems=0;
private static String LOG = "testwidgets";
ArrayList<String> feedsPubDate;
@SuppressWarnings("deprecation")
@Override
public void onStart(Intent intent, int startId) {
Log.i(LOG, "Called");
// Create some random data
feedsPubDate=new ArrayList<String>();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
.getApplicationContext());
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
ComponentName thisWidget = new ComponentName(getApplicationContext(),
MyWidgetProvider.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
Log.w(LOG, "From Intent" + String.valueOf(allWidgetIds.length));
Log.w(LOG, "Direct" + String.valueOf(allWidgetIds2.length));
for (int widgetId : allWidgetIds) {
// Create some random data
///////////////////////////////////////////////////////////////////////////
RemoteViews remoteViews = new RemoteViews(this
.getApplicationContext().getPackageName(),
R.layout.widget_layout);
Log.d("numberOfItems intially", String.valueOf(numberOfItems));
try {
numberOfItems=doTestFeed();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Set the text
remoteViews.setTextColor(R.id.title3,Color.WHITE);
remoteViews.setTextViewText(R.id.title3," "+
String.valueOf(numberOfItems));
Log.w(LOG, String.valueOf(numberOfItems));
////////////////////////////////////////////////////////////////////////////
// Register an onClickListener
Intent clickIntent = new Intent(this.getApplicationContext(),
MyWidgetProvider.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
allWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.title3, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
stopSelf();
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
int doTestFeed() throws MalformedURLException, ParseException
{
Log.d("msg"," in do test feed");
InputStream is = null;
int x = 0;
URL myURL = new URL("http://yunn.yu.edu.jo/index.php?option=com_content&view=category&id=55&layout=blog&Itemid=104&format=feed&type=rss");
try {
URLConnection conn = myURL.openConnection();
is = conn.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
XmlPullParserFactory pullParserFactory;
try {
pullParserFactory = XmlPullParserFactory.newInstance();
XmlPullParser parser = pullParserFactory.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, null);
Log.d("msg","before making parsing");
x=parseXML(parser);
Log.d("msg","after making parsing");
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.d("msg"," done testing");
return x;
}
//////////////////////////////////////////////////////////////////////////////////
@SuppressLint("SimpleDateFormat")
private int parseXML(XmlPullParser parser) throws XmlPullParserException,IOException, ParseException
{
Log.d("msg"," in parser");
int eventType = parser.getEventType();
int getElement=0;
String pubDate=null;
while (eventType != XmlPullParser.END_DOCUMENT){
String tagName = null;
switch (eventType){
//----------------------------------//
case XmlPullParser.START_DOCUMENT:
{
// do nothing
}
break;
//----------------------------------//
case XmlPullParser.START_TAG:
{ tagName = parser.getName();
if ("item".equals(tagName)){
getElement=1;
} else if (getElement!=0){
if ("pubDate".equals(tagName)){
pubDate= parser.nextText();
feedsPubDate.add(pubDate);
Log.d("value",pubDate);
}
}
}
break;
//----------------------------------//
case XmlPullParser.END_TAG:
{ tagName = parser.getName();
if (tagName.equalsIgnoreCase("item") && getElement != 0){
}
}
break;
//----------------------------------//
}// end-switch.
eventType= parser.next();
}// end-while.
int i=0;
SharedPreferences sp = getSharedPreferences("tempData", 0);
String dateStringA=sp.getString("recentPubDate", null);
Log.d("oldest date",dateStringA);
for(String s : feedsPubDate )
{
String dateStringB = feedsPubDate.get(i);
SimpleDateFormat parserSDF = new SimpleDateFormat("EEE, DD MMM yyyy HH:mm:ss");
Date dateA = parserSDF.parse(dateStringA);
Date dateB = parserSDF.parse(dateStringB);
if (dateA.compareTo(dateB) < 0) {
Log.d("imp msg","one new item");
numberOfItems++;
}
i++;
}
Log.d("update result", String.valueOf(numberOfItems));
// Toast.makeText(GeneralNews.this,"The size of the list"+feedsTitles.size() , Toast.LENGTH_LONG).show();
return numberOfItems;
} //end xmlParser method.
//////////////////////////////////////////////////////////////////////////////////
}
3)StackTrace:
09-02 09:41:08.476: E/AndroidRuntime(1606): FATAL EXCEPTION: main
09-02 09:41:08.476: E/AndroidRuntime(1606): java.lang.RuntimeException: Unable to start service com.example.testfeeds.UpdateWidgetService@410a33c8 with Intent { cmp=com.example.testfeeds/.UpdateWidgetService (has extras) }: android.os.NetworkOnMainThreadException
09-02 09:41:08.476: E/AndroidRuntime(1606): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2673)
09-02 09:41:08.476: E/AndroidRuntime(1606): at android.app.ActivityThread.access$1900(ActivityThread.java:141)
09-02 09:41:08.476: E/AndroidRuntime(1606): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1331)
09-02 09:41:08.476: E/AndroidRuntime(1606): at android.os.Handler.dispatchMessage(Handler.java:99)
09-02 09:41:08.476: E/AndroidRuntime(1606): at android.os.Looper.loop(Looper.java:137)
09-02 09:41:08.476: E/AndroidRuntime(1606): at android.app.ActivityThread.main(ActivityThread.java:5041)
09-02 09:41:08.476: E/AndroidRuntime(1606): at java.lang.reflect.Method.invokeNative(Native Method)
09-02 09:41:08.476: E/AndroidRuntime(1606): at java.lang.reflect.Method.invoke(Method.java:511)
09-02 09:41:08.476: E/AndroidRuntime(1606): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
09-02 09:41:08.476: E/AndroidRuntime(1606): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-02 09:41:08.476: E/AndroidRuntime(1606): at dalvik.system.NativeStart.main(Native Method)
09-02 09:41:08.476: E/AndroidRuntime(1606): Caused by: android.os.NetworkOnMainThreadException
09-02 09:41:08.476: E/AndroidRuntime(1606): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
09-02 09:41:08.476: E/AndroidRuntime(1606): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
09-02 09:41:08.476: E/AndroidRuntime(1606): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
09-02 09:41:08.476: E/AndroidRuntime(1606): at java.net.InetAddress.getAllByName(InetAddress.java:214)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpEngine.connect(HttpEngine.java:311)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
09-02 09:41:08.476: E/AndroidRuntime(1606): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
09-02 09:41:08.476: E/AndroidRuntime(1606): at com.example.testfeeds.UpdateWidgetService.doTestFeed(UpdateWidgetService.java:136)
09-02 09:41:08.476: E/AndroidRuntime(1606): at com.example.testfeeds.UpdateWidgetService.onStart(UpdateWidgetService.java:81)
09-02 09:41:08.476: E/AndroidRuntime(1606): at android.app.Service.onStartCommand(Service.java:450)
09-02 09:41:08.476: E/AndroidRuntime(1606): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2656)
09-02 09:41:08.476: E/AndroidRuntime(1606): ... 10 more
09-02 09:41:13.295: E/Trace(2270): error opening trace file: No such file or directory (2)
答案 0 :(得分:3)
您正在从主服务线程访问网络,将网络访问权限更改为后台线程(异步任务)或使用IntentService
请注意,services与其他应用程序对象一样,在其托管进程的主线程中运行。这意味着,如果您的服务要进行任何CPU密集型(例如MP3播放)或阻止(例如网络)操作,它应该生成自己的线程来执行该工作。< / p>
请参阅服务的docs
答案 1 :(得分:2)
从AsyncTask
调用此函数doTestFeed();
答案 2 :(得分:1)
您无法直接更新您的用户界面...在您的日志中,问题是 NetworkOnMainThreadException ...
所以你应该使用AsyncTask,或者你可以使用 IntentService ,或者也可以使用 Thread with Handler 类......
此错误通过使用 StrictMode.ThreadPolicy()来解决。但它也不适用于较低版本..
用AsyncTask替换 doTestFeed()的代码。 希望这会对你有帮助..
答案 3 :(得分:1)
android.os.NetworkOnMainThreadException
将doTestFeed()
的代码替换为AsyncTask
。
答案 4 :(得分:1)
如果您收到NetworkMainThread异常,则尝试在主线程中进行网络调用。 你需要使用异步任务(后台进程)进行调用,不要在主线程中执行此操作。
否则在oncreate()方法之后添加这段代码
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);