1

This is my Service which does network operation. But it is throwing NetworkonMainThreadException which i understand android upper version doesn't allows network operation under main thread. Now i want to use Async Task for this purpose. I am not sure which are all code i need to add under Async Task from Service Class to actually make the code complete. Below is my Service Code :

public class NewsTickerDataService extends Service {

 @Override
    public void onStart(Intent aIntent, int aStartId) {
        super.onStart(aIntent, aStartId);   
        RemoteViews _views = buildUpdatedViews(this);   
        ComponentName _widget = 
            new ComponentName(this, NewsTicker.class);
        AppWidgetManager _manager = 
            AppWidgetManager.getInstance(this); 
        _manager.updateAppWidget(_widget, _views);
    }

    @Override
    public IBinder onBind(Intent aParamIntent) {
        // not supporting binding   
        return null;
    }

    private RemoteViews buildUpdatedViews(Context aContext) {
        List<Story> _stories = getStories();
        RemoteViews _result = new RemoteViews(
            aContext.getPackageName(), 
            R.layout.activity_main
        );

        if (_stories.isEmpty()) {
            _result.setTextViewText(R.id.title, 
                "Sadly there's nothing to read today.");
        } else {
            _result.setTextViewText(
                R.id.title, _stories.get(0).getTitle());
        }
        return _result;
    }

    private List<Story> getStories() {
        try {
            URL _url = new URL("http://search.twitter.com" +
                "/search.atom?q=%23uml&" + 
                "result_type=mixed&count=5"
            );
            InputStream _in = _url.openStream();
            return parse(new InputSource(_in));
        } catch (Exception anExc) {
            Log.e("NewsTicker", anExc.getMessage(), anExc);
            return new ArrayList<Story>();
        }
    }

    private List<Story> parse(InputSource aSource)
    throws Exception {
        SAXParserFactory _f = SAXParserFactory.newInstance();
        SAXParser _p = _f.newSAXParser();
        XMLReader _r = _p.getXMLReader();

        AbstractParser _h = AbstractParser.newAtomParser();
        _r.setContentHandler(_h);   
        _r.parse(aSource);

        return _h.getStories();
    }

}

Async Task Code :

public class YourAsyncTask extends AsyncTask<String, Void, String>{

        @Override
        protected String doInBackground(String... params) {
            // your load work
            //return myString;
        }

        @Override
        protected void onPostExecute(String result) {

        }

    }

Can someone please help me to integrate Async Task into same code. Thanks

user45678
  • 1,504
  • 6
  • 29
  • 58
  • 2
    `getStories()` and `parse()` need to be in `doInBackground()`. Pretty simple, actually -- if you access the network, it needs to be off the UI thread. `doInBackground()` runs off the UI. – 323go Sep 23 '13 at 14:22
  • I'd suggest looking int IntentService. This post may be of help to you. http://stackoverflow.com/questions/15524280/service-vs-intent-service – Prmths Sep 23 '13 at 14:26
  • Ya..I understand this methods needs to be in "doInBackground()", but I am kinda of confused with "return" statement of both. Can u show me Integration ? Thanks – user45678 Sep 23 '13 at 14:26

2 Answers2

0

Yes, I'd suggest IntentService too!

IntentService example

public class MyService extends IntentService {

private int STOP_DOWNLOAD = false;
public static int UPDATE_PROGRESS = 0;

public MyService() {
    super("myservice");
}

@Override
public void onCreate() {
    super.onCreate();
}

@Override
protected void onHandleIntent(Intent intent) {

    // Network Task : download ?

    // Send some data to the receiver
    Bundle resultData = new Bundle();
    resultData.putInt("progress", progress);
    receiver.send("update", resultData);
}

private void stopDownload() {
    this.STOP_DOWNLOAD = true;
    // Stop the download : use this boolean into onHandleIntent
}

}

The receiver

public class MyReceiver extends ResultReceiver {

Context context;

public MyReceiver(Context mContext) {
    super(handler);
    context = mContext;
}

@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
    super.onReceiveResult(resultCode, resultData);

    if (resultCode == "update") {


        String something = resultData.getString(MyService.SOMETHING);

    }
}

}

Start the service in an Activity : startService(...)

athom
  • 313
  • 1
  • 11
  • Thanks Antho but at present i would not like to change my whole code and work with the same integration formula. Thanks if you can help me with that. – user45678 Sep 23 '13 at 15:04
0

From the onStart() of your service class make network operation

        YourAsyncTask.execute(url);

Async task code

    public class YourAsyncTask extends AsyncTask<String, Void, String>{

    @Override
    protected String doInBackground(String... params) {
        // your load work
        DefaultHttpClient client = new DefaultHttpClient();
         HttpGet httpGet = new HttpGet(url);
    try {
      HttpResponse execute = client.execute(httpGet);
      InputStream content = execute.getEntity().getContent();

      BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
      String s = "";
      while ((s = buffer.readLine()) != null) {
        response += s;
      }

    } catch (Exception e) {
      e.printStackTrace();
    }



  return response;
        //return myString;
    }

    @Override
    protected void onPostExecute(String result) {
       //HERE CALL YOUR PARSE METHOD

       //AFTER PARSING CALL buildUpdatedViews(Context aContext , stories)
    }

}
Handroid
  • 399
  • 1
  • 2
  • 13