Reputation: 1514
I am trying to run below code it gives exception saying:
java.lang.RuntimeException: Unable to start service com.example.testfeeds.UpdateWidgetService@410a33c8 with Intent { cmp=com.example.testfeeds/.UpdateWidgetService (has extras) }: android.os.NetworkOnMainThreadException
which i understand that new version of Android won't allow network operations in main thread. People suggested me to use Async Task but I don't know how to use that. Can someone show me in below code?
Thanks in advance
public class WidgetService extends Service {
/*
* So pretty simple just defining the Adapter of the listview
* here Adapter is ListProvider
* */
/*@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
int appWidgetId = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
return (new ListProvider(this.getApplicationContext(), intent));
}*/
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(), WidgetProvider.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.empty_view,Color.WHITE);
remoteViews.setTextViewText(R.id.empty_view," "+ String.valueOf(numberOfItems));
Log.w(LOG, String.valueOf(numberOfItems));
////////////////////////////////////////////////////////////////////////////
// Register an onClickListener
Intent clickIntent = new Intent(this.getApplicationContext(),
WidgetProvider.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.empty_view, 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 = null;
try {
dateA = parserSDF.parse(dateStringA);
} catch (java.text.ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Date dateB = null;
try {
dateB = parserSDF.parse(dateStringB);
} catch (java.text.ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
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.
//////////////////////////////////////////////////////////////////////////////////
}
Upvotes: 8
Views: 37317
Reputation: 1329
If API version is 11 or above android:targetSDk does not allow netwrok on main thread But it works in below in HoneyComb.n
Try to remove android:targetSdkVersion line from your manifest. I did this in 3rd party code and work for me most of time.
It worked for me.
Upvotes: 0
Reputation: 9429
it is about ui thread. I guess Services have some issues with ui thread. onPostExecutes have to be run on ui thread. so, because of Services have not ui thread, it breaks on executing onPostExecute on non-ui thread.
I suggest
new Thread(){
public void run() {
Object result=null;
Looper l = Looper.getMainLooper();
Handler h = new Handler(l);
h.post(new Runnable() {
@Override
public void run() {
if (result != null){
response.OnResponse(true, "", result);
} else {
response.OnResponse(false, errMessage, null);
}
}
});
};
}.start();
of course, this has not Thread pool in AsyncTask, but you can convert this code to use a Thread pool.
Upvotes: 2
Reputation: 77904
As example:
You have log in Activity and when you press "Login" application need to validate against Service and switch to main Activity:
private class HeavyTask extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String... args) {
//do something here
// like tell to Service to do some async task
return null;
}
protected void onPostExecute(Void results) {
// here actually we wait any event from Service about task done
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
startActivity(new Intent().setClass(FirstLoginActivity.this, MainActivity.class).setData(getIntent().getData()));
finish();
}
}, 1000);
}
}, 500);
}
}
And this is how I call it:
HeavyTask task = new HeavyTask();
task.execute(user, passwordText, login_outbound_proxy); // as example
Pretty simple example that will help you to sort things out in addition to theory
Upvotes: 0
Reputation: 22527
A simple example:
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) {
}
}
Use new YourAsyncTask ().execute()
to call it.
Upvotes: 1
Reputation: 51411
I think this question might be helpful for you: How to use AsyncTask
You can make your AsyncTask an inner class of your Service, and do your network-operations in the doInBackground()
method of AsyncTask. From doInBackground()
you can return any kind of data to the onPostExecute()
method of AsyncTask, where you can do further stuff with the received data.
And here, an AsyncTask example: AsyncTask Android example
Upvotes: 10