0

我的应用程序有问题,该应用程序是获取新闻提要的应用程序,并且该应用程序有一个小部件,该小部件通过添加到 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)更新小部件服务:

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)堆栈跟踪:

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)
4

5 回答 5

3

您正在从服务的主线程访问网络,将网络访问更改为后台线程(异步任务)或使用IntentService

请注意,服务与其他应用程序对象一样,在其托管进程的主线程中运行。这意味着,如果您的服务要执行任何 CPU 密集型(例如 MP3 播放)或阻塞(例如网络)操作,它应该生成自己的线程来完成这项工作

查看服务文档

于 2013-09-02T09:52:32.873 回答
2

doTestFeed();从 AsyncTask调用此函数

于 2013-09-02T09:55:27.620 回答
1

您不能直接更新您的 UI ...在您的日志中,问题是NetworkOnMainThreadException ...

所以你应该使用 AsyncTask 或者你可以使用IntentService或者你也可以使用Thread 和 Handler类......

并且这个错误也可以通过使用StrictMode.ThreadPolicy()来解决..但它也不适用于较低版本..

将doTestFeed()的代码替换为AsyncTask。希望对你有帮助..

于 2013-09-02T10:04:28.373 回答
1
android.os.NetworkOnMainThreadException

将 的代码替换doTestFeed()AsyncTask

于 2013-09-02T10:05:38.377 回答
1

如果你得到 NetworkMainThread Exception,你正试图在主线程中进行网络调用。您需要使用异步任务(后台进程)进行调用,不要在主线程中执行此操作。

否则在 oncreate() 方法之后添加这段代码

             StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
            .permitAll().build();
            StrictMode.setThreadPolicy(policy); 
于 2013-09-02T10:27:05.560 回答