I'm trying to build an RSS reader and put the rss feed fetch as ansyctask,
that returns a feed in list view, or returns a text view saying "no internet connection"
but the app still crashes, I don't know what's wrong, can you help please.
here is the code:
package rss;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.TextView;
import com.enporan.polytechoran.R;
public class RSSActivity extends ActionBarActivity {
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news);
rssfeedget alpha = new rssfeedget();
alpha.execute();
}
private class rssfeedget extends AsyncTask<String, Void, FeedSource> {
protected void onPreExecute() {
}
#Override
protected FeedSource doInBackground(String... params) {
FeedSource f = new HttpFeedSource();
if(f!=null)
return f;
else {
return null;
}
}
#Override
protected void onPostExecute(FeedSource result){
ListView rssItemList = (ListView) findViewById(R.id.rssListview);
rssItemList.setVerticalFadingEdgeEnabled(true);
if(doInBackground()==null){
TextView tv= (TextView) findViewById(R.id.textView2);
tv.setText("No internet Connection...");
}
else{
RSSItemAdapter adapter = new RSSItemAdapter(getApplicationContext(), R.layout.rssitem, doInBackground().getFeed());
rssItemList.setAdapter(adapter);
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_news, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
As #coelho pointed out, the FeedSource.getFeed() shouldn't be executed in the UI thread. You must now that the onPreExecute and onPostExecute methods are executed inside the UI thread, while the doInBackground method isn't.
Here's what you can do: in your AsyncTask class, add a private member: private List<RSSItem> result; (replace RSSItem here by the type of the collection returned by getFeed).
Then, update doInBackground:
FeedSource f = new HttpFeedSource();
if (f != null)
return f;
else {
this.result = f.getFeed(); // Execute getFeed in doInBackground
return null;
}
Then, in the onPostExecute method, you'll be able to use this private member as this:
RSSItemAdapter adapter = new RSSItemAdapter(getApplicationContext(), R.layout.rssitem, this.result);
Here is the code:
private class rssfeedget extends AsyncTask<String, Void, List<RSSItem>> {
private List<RSSItem> result;
protected void onPreExecute() {
}
#Override
protected List<RSSItem> doInBackground(String... params) {
FeedSource f = new HttpFeedSource();
if(f.getFeed()==null)
return null;
else {
this.result = f.getFeed(); // Execute getFeed in doInBackground
return result;
}
}
#Override
protected void onPostExecute(List<RSSItem> result){
if(doInBackground()==null){
TextView tv= (TextView) findViewById(R.id.textView2);
tv.setText("No internet Connection...");
}
else{
ListView rssItemList = (ListView) findViewById(R.id.rssListview);
rssItemList.setVerticalFadingEdgeEnabled(true);
RSSItemAdapter adapter = new RSSItemAdapter(getApplicationContext(), R.layout.rssitem, this.result);
rssItemList.setAdapter(adapter);
}
}
}
Related
I have a gridView in my app containing images. Images are loaded from json over the web. I want that when a user click on any image in the gridView a new activity will open container the image clicked by the user. The images are loaded from links defined in json. I tried but didn't get desired result.
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import com.dragedy.dream.adapter.MyArrayAdapter;
import com.dragedy.dream.model.MyDataModel;
import com.dragedy.dream.parser.JSONParser;
import com.dragedy.dream.utils.InternetConnection;
import com.dragedy.dream.utils.Keys;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class memechoose extends AppCompatActivity {
private GridView gridView;
private ArrayList<MyDataModel> list;
private MyArrayAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memechoose);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
/**
* Array List for Binding Data from JSON to this List
*/
list = new ArrayList<>();
/**
* Binding that List to Adapter
*/
adapter = new MyArrayAdapter(this, list);
/**
* Getting List and Setting List Adapter
*/
gridView = (GridView) findViewById(R.id.gridView);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i= new Intent(memechoose.this, MemeEditorActivity.class);
i.putExtra("image_path", list.get(position).getImage());
startActivity(i);
}
});
/**
* Just to know onClick and Printing Hello Toast in Center.
*/
if (InternetConnection.checkConnection(getApplicationContext())) {
new GetDataTask().execute();
}
}
/**
* Creating Get Data Task for Getting Data From Web
*/
class GetDataTask extends AsyncTask<Void, Void, Void> {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
/**
* Progress Dialog for User Interaction
*/
dialog = new ProgressDialog(memechoose.this);
dialog.setTitle("Hey Wait Please...");
dialog.setMessage("I am getting your JSON");
dialog.show();
}
#Nullable
#Override
protected Void doInBackground(Void... params) {
/**
* Getting JSON Object from Web Using okHttp
*/
JSONObject jsonObject = JSONParser.getDataFromWeb();
try {
/**
* Check Whether Its NULL???
*/
if (jsonObject != null) {
/**
* Check Length...
*/
if(jsonObject.length() > 0) {
/**
* Getting Array named "contacts" From MAIN Json Object
*/
JSONArray array = jsonObject.getJSONArray(Keys.KEY_MEME);
/**
* Check Length of Array...
*/
int lenArray = array.length();
if(lenArray > 0) {
for(int jIndex = 0; jIndex < lenArray; jIndex++) {
/**
* Creating Every time New Object
* and
* Adding into List
*/
MyDataModel model = new MyDataModel();
/**
* Getting Inner Object from contacts array...
* and
* From that We will get Name of that Contact
*
*/
JSONObject innerObject = array.getJSONObject(jIndex);
String image = innerObject.getString(Keys.KEY_MEME_PIC);
/**
* Getting Object from Object "phone"
*/
model.setImage(image);
/**
* Adding name and phone concatenation in List...
*/
list.add(model);
}
}
}
} else {
}
} catch (JSONException je) {
Log.i(JSONParser.TAG, "" + je.getLocalizedMessage());
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
dialog.dismiss();
/**
* Checking if List size if more than zero then
* Update ListView
*/
if(list.size() > 0) {
adapter.notifyDataSetChanged();
} //else {
// Snackbar.make(findViewById(R.id.parentLayout), "No Data Found", Snackbar.LENGTH_LONG).show();
// }
}
}
}
and the activity in which i want to display the images is as follows:
public class MemeEditorActivity extends AppCompatActivity {
private Toolbar toolbar;
private MemeEditorActivity selfRef;
private SharedPreferences setting;
private LinearLayout linlaHeaderProgress;
private float memeEditorLayoutWidth;
private float memeEditorLayoutHeight;
private LinearLayout tutorial;
private LinearLayout memeEditorLayout;
private MemeEditorView memeEditorView;
private ImageView forwardButtonImageView;
private Bitmap memeBitmap;
private File cacheImage_forPassing;
private File myDir;
private String dataDir;
private boolean firsttimes;
private boolean tutorialPreference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_meme_editor);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
selfRef = this;
// Transparent bar on android 4.4 or above
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT)
{
Window window = getWindow();
// Translucent status bar
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// Translucent navigation bar
window.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
// Initialize progress bar
linlaHeaderProgress = (LinearLayout)findViewById(R.id.linlaHeaderProgress);
linlaHeaderProgress.bringToFront();
// Initialize tutorial
setting = PreferenceManager
.getDefaultSharedPreferences(MemeEditorActivity.this);
SharedPreferences prefre = getSharedPreferences("Meme_Pref", Context.MODE_PRIVATE);
firsttimes = prefre.getBoolean("Meme_Pref", true);
tutorialPreference = setting.getBoolean("Tutor_Preference", false);
SharedPreferences.Editor firstTimeEditor = prefre.edit();
// See if tutorial is needed to be shown
tutorial = (LinearLayout)findViewById(R.id.meme_editor_tutorial);
tutorial.setEnabled(false);
tutorial.setOnClickListener(new View.OnClickListener()
{
# Override
public void onClick(View view)
{
tutorial.setVisibility(View.GONE);
tutorial.setEnabled(false);
}
});
if(firsttimes)
{
tutorial.setVisibility(View.VISIBLE);
tutorial.bringToFront();
tutorial.setEnabled(true);
firstTimeEditor.putBoolean("Meme_Pref", false);
firstTimeEditor.commit();
}
else if(tutorialPreference)
{
tutorial.setVisibility(View.VISIBLE);
tutorial.bringToFront();
tutorial.setEnabled(true);
tutorialPreference = setting.getBoolean("Tutor_Preference", false);
}
else
{
tutorial.setVisibility(View.GONE);
tutorial.setEnabled(false);
}
// Get the data directory for the app
PackageManager m = getPackageManager();
dataDir = getPackageName();
try
{
PackageInfo p = m.getPackageInfo(dataDir, 0);
dataDir = p.applicationInfo.dataDir;
myDir = new File(dataDir+"/cache");
if(!myDir.exists())
myDir.mkdirs();
if(myDir.setWritable(true))
Log.i("meme", "myDir is writable");
else
Log.i("meme", "myDir is not writable");
}catch(PackageManager.NameNotFoundException e)
{
Log.w("yourtag", "Error Package name not found ", e);
}
// Get the intent and get the image path to be the meme image
Intent shareIntent = getIntent();
String imagePath = shareIntent.getStringExtra("image_path");
// Create the SandboxView
setting = PreferenceManager
.getDefaultSharedPreferences(MemeEditorActivity.this);
// final int memeSize = Integer.valueOf(setting.getString("image_size","720"));
final int memeSize = setting.getInt("image_size", 720);
Log.i("meme", "memeSize = "+memeSize);
memeEditorLayout = (LinearLayout)findViewById(R.id.memeEditorLayout);
memeEditorLayout.setGravity(Gravity.CENTER);
try
{
Log.i("imagePath", imagePath);
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
memeEditorView = new MemeEditorView(this, bitmap);
memeEditorView.setLayoutParams(new ViewGroup.LayoutParams(memeSize, memeSize));
// Scale the sand box and add it into the layout
ViewTreeObserver viewTreeObserver = memeEditorLayout
.getViewTreeObserver();
// For getting the width and height of a dynamic layout during
// onCreate
viewTreeObserver
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
#RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
# Override
public void onGlobalLayout()
{
memeEditorLayout.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
memeEditorLayoutWidth = memeEditorLayout.getHeight();
memeEditorLayoutHeight = memeEditorLayout.getWidth();
float scalingFactor = memeEditorLayoutWidth/(float)memeSize;
Log.i("memeEditorLayoutWidth", Float.toString(memeEditorLayoutWidth));
Log.i("ScaleFactor", Float.toString(scalingFactor));
memeEditorView.setScaleX(scalingFactor);
memeEditorView.setScaleY(scalingFactor);
}
});
memeEditorLayout.addView(memeEditorView);
// Set save button on click method
forwardButtonImageView = (ImageView)findViewById(R.id.forwardButtonImage);
forwardButtonImageView.setOnClickListener(new View.OnClickListener()
{
# Override
public void onClick(View arg0)
{
forwardButtonImageView.setEnabled(false);
Forward forward = new Forward();
forward.execute();
}
});
}catch(OutOfMemoryError e)
{
Toast.makeText(selfRef, "Your device is out of memory.", Toast.LENGTH_LONG).show();
finish();
}catch(Exception e)
{
Log.i("Meme Editor Activity", e.toString());
Toast.makeText(selfRef, "Ops, something went wrong.", Toast.LENGTH_LONG).show();
finish();
}
}
// Delete a files
private void deleteFile(File file)
{
if(file!=null)
{
Log.i("deleteFile", file.toString()+((file.exists())?" is Exist.":"is not exist!!!!"));
// Check if the file exist
if(file.exists())
// Clear the file inside if it is a directory
if(file.isDirectory())
{
String[] children = file.list();
for(int i = 0;i<children.length;i++)
{
File f = new File(file, children[i]);
if(f.delete())
Log.i("deleteFile", f.getAbsolutePath()+" is deleted....");
else
Log.i("deleteFile", f.getAbsolutePath()+" is not deleted!!!!");
}
}
}
}
# Override
protected void onPause()
{
// Hide the progress bar
linlaHeaderProgress.setVisibility(View.GONE);
forwardButtonImageView.setEnabled(true);
super.onPause();
}
# Override
protected void onResume()
{
super.onResume();
memeEditorView.setEnabled(true);
memeEditorView.resume();
}
# Override
protected void onDestroy()
{
// Try to delete cache if possible
// deleteFile(myDir);
// bp_release();
//memeEditorView.destroyDrawingCache();
super.onDestroy();
}
# Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.meme_editor, menu);
return true;
}
# Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch(item.getItemId())
{
case R.id.reset_sandbox:
memeEditorView.reset();
return true;
case R.id.action_settings:
Intent intent = new Intent(selfRef, MainActivity.class);
startActivity(intent);
return true;
case android.R.id.home:
// When the action bar icon on the top right is clicked, finish this
// activity
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// save image to a specific places
private void saveImage()
{
// Create the file path and file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fname = timeStamp+".png";
cacheImage_forPassing = new File(myDir, fname);
// Remove duplicates
if(cacheImage_forPassing.exists())
cacheImage_forPassing.delete();
// Try save the bitmap
try
{
FileOutputStream out = new FileOutputStream(cacheImage_forPassing);
memeBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
Log.i("memeCacheLocation", cacheImage_forPassing.toString());
}catch(Exception e)
{
e.printStackTrace();
}
}
// Async task for onClick
class Forward extends AsyncTask<Object,Object,Object>
{
// Before forwarding
# Override
protected void onPreExecute()
{
super.onPreExecute();
linlaHeaderProgress.setVisibility(View.VISIBLE);
linlaHeaderProgress.bringToFront();
memeEditorView.pause();
memeEditorView.invalidate();
}
// Forwarding
# Override
protected String doInBackground(Object ... arg0)
{
Intent forward = new Intent(selfRef, MainActivity.class);
memeEditorView.setDrawingCacheEnabled(true);
memeEditorView.buildDrawingCache();
memeBitmap = Bitmap.createBitmap(memeEditorView.getDrawingCache());
saveImage();
forward.putExtra("cs4295.memcreator.memeImageCache",
cacheImage_forPassing.getPath());
startActivity(forward);
memeEditorView.setDrawingCacheEnabled(false);
return "DONE";
}
// After forwarding
# Override
protected void onPostExecute(Object result)
{
linlaHeaderProgress.setVisibility(View.GONE);
super.onPostExecute(result);
}
}
// Clear the Bitmap from memory
private void bp_release()
{
if(memeBitmap!=null&&!memeBitmap.isRecycled())
{
memeBitmap.recycle();
memeBitmap = null;
}
}
}
#AC-OpenSource E/BitmapFactory: Unable to decode stream:
java.io.FileNotFoundException:
/http:/static2.businessinsider.com/image/56e3189152bcd0320c8b5cf7-480/sammy-griner-success-kid-meme.jpg:
open failed: ENOENT (No such file or directory)
You have a slash before http
I am trying to make an application to show current epoch time which is being updated real time on start of a button and another button stops it. I am trying to use Async task for that purpose but I am stuck with errors as not being taken in async task can not be applied to java.lang.string.
Please help.
package com.example.sangeeta.epochtimer;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.os.AsyncTask;
import android.provider.Settings.System;
import android.os.SystemClock;
import java.util.Calendar;
public class MainActivity extends ActionBarActivity {
TextView textonee;
Button start, stop;
long epochtime;
boolean pressstate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pressstate = false;
start = (Button) findViewById(R.id.button1);
stop = (Button) findViewById(R.id.button2);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pressstate = true;
new Operation().execute("");
}
});
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//shutdown();
pressstate = false;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class Operation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
while (pressstate) {
Calendar rightNow = Calendar.getInstance();
// offset to add since we're not UTC
//long offset = rightNow.get(Calendar.ZONE_OFFSET) +
//rightNow.get(Calendar.DST_OFFSET);
//long sinceMidnight = (rightNow.getTimeInMillis() + offset) %
//(24 * 60 * 60 * 1000);
epochtime=rightNow.getTimeInMillis();
this.publishProgress(""+epochtime);
}
return null;
}
protected void onPostExecute(String result) {
textonee = (TextView) findViewById(R.id.textViewepo);
//textonee.setText("" + epochtime); // txt.setText(result);
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
super.onProgressUpdate(result);
textonee.setText(result[0]);
}
}
};
You need to override onProgressUpdate instead of onPostExecute in order to publish progress correctly.
private class Operation extends AsyncTask<String, String, Void> {
#Override
protected void doInBackground(String... params) {
while (pressstate) {
Calendar rightNow = Calendar.getInstance();
// offset to add since we're not UTC
//long offset = rightNow.get(Calendar.ZONE_OFFSET) +
//rightNow.get(Calendar.DST_OFFSET);
//long sinceMidnight = (rightNow.getTimeInMillis() + offset) %
//(24 * 60 * 60 * 1000);
epochtime=rightNow.getTimeInMillis();
this.publishProgress(""+epochtime);
}
}
protected void onProgressUpdate(String result) {
textonee = (TextView) findViewById(R.id.textViewepo);
//textonee.setText("" + epochtime); // txt.setText(result);
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
super.onProgressUpdate(result);
textonee.setText(result[0]);
}
protected void onPostExecute(Void... voids) {
// NO-OP
}
private class Operation extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
while (pressstate) {
Calendar rightNow = Calendar.getInstance();
// offset to add since we're not UTC
//long offset = rightNow.get(Calendar.ZONE_OFFSET) +
//rightNow.get(Calendar.DST_OFFSET);
//long sinceMidnight = (rightNow.getTimeInMillis() + offset) %
//(24 * 60 * 60 * 1000);
epochtime=rightNow.getTimeInMillis();
this.publishProgress(""+epochtime);
}
return null;
}
protected void onPostExecute(String result) {
textonee = (TextView) findViewById(R.id.textViewepo);
//textonee.setText("" + epochtime); // txt.setText(result);
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
super.onProgressUpdate(result);
textonee.setText(result);
}
}
Try this
I have a instance variable(art) of main activity class getting assigned with a value in onPostExecution method.Log statements prints the value of art in onPostExecute method.
But the value of art is null after the onPostExecute method.
public class MainActivity extends ActionBarActivity implements OnItemClickListener {
ListView listView1;
String[] dummyData = {"sunday","monday","tuesday","wednesday","thursday","friday","saturday","sunday","monday","tuesday",
"wednesday","thursday","friday","saturday","sunday","monday","tuesday","wednesday","thursday","friday","saturday"};
ArrayAdapter<String> adapter ;
ArrayList<String> summery = new ArrayList<String>(4);
ArrayList<String> links = new ArrayList<String>(4);
Elements art;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String stringUrl = "https://techcards.wordpress.com";
Fetch fetch = new Fetch();
fetch.execute(stringUrl);
try{
for (int i =0;i<art.size() ;i++ ) {
Log.v("articles after post executive",art.get(i).toString());
links.add(i,art.get(i).getElementsByTag("a").toString());
Log.v("links",art.toString());
summery.add(i,art.get(i).getElementsByTag("p").text());
}
}catch(NullPointerException e){
e.printStackTrace();
System.out.println("art is null");
}
listView1 = (ListView) findViewById(R.id.listView1);
adapter = new ArrayAdapter<String>(this,R.layout.single_row,R.id.textView2, links);
listView1.setAdapter(adapter);
listView1.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
TextView t = (TextView) view.findViewById(R.id.textView2);
String text =(String) t.getText();
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();//this makeText is a static method
}
// Fetch AsyncTask
private class Fetch extends AsyncTask<String, Void, Elements> {
#Override
protected Elements doInBackground(String... params) {
Elements articles = null;
try {
// Connect to the web site
Document doc = Jsoup.connect(params[0]).get();
Element main =doc.getElementById("content").getElementById("primary").
getElementById("main");
articles = main.getElementsByClass("entry-summary");
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO exception");
}
return articles;
}
protected void onPostExecute(Elements result) {
art = result;
for (int i =0;i<art.size() ;i++ ) {
Log.v("links in post executive",art.get(i).getElementsByTag("a").toString());
Log.v("summery in post executive",art.get(i).getElementsByTag("p").text());
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
art is giving null pointer exception when i'm trying to use it to update links and summery.
onPostExecute method run when doInBackground execution complete. so add data in adapter in onPostExecute instead of just after starting AsyncTask :
#Override
protected void onPostExecute(Elements result) {
super.onPostExecute(result);
// 1. Add data in summery from result
// 2. Pass summery to Adapter constructor
adapter = new ArrayAdapter<String>(MainActivity.this,R.layout.single_row,
R.id.textView2, links);
listView1.setAdapter(adapter);
}
AsyncTask works asynchronously. Those lines after:
fetch.execute(stringUrl);
doesn't work after onPostExecute but it works simultaneously (or so) with the code inside AsyncTask. That's why AsyncTask is called AsyncTask.
And that's why your art variable is null since onPostExecute doesn't get called yet.
I've a listview with some static data. When the refresh activity is done, some data need to be updated in listview. The problem is once the refresh gets completed, the new items are not updated.
MainActivity.class
public class MainActivity extends ActionBarActivity {
SwipeRefreshLayout swipeLayout;
String[] players = {"Dravid","Ganguly","Sachin","Irfan pathan","Balaji","Bhuvi","Praveen"};
ListView listView;
ArrayAdapter<String> adapter = null;
ArrayList al = new ArrayList();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listView);
for (int i =0; i<players.length; i++)
{
Bean b = new Bean();
b.setName(players[i]);
al.add(b);
}
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,players);
listView.setAdapter(adapter);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
swipeLayout.setRefreshing(true);
new updateItems().execute();
}
});
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
class updateItems extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
String[] newitems = {"Ishant sharma","Ramesh power","Kaif"};
// adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,newitems);
for (int j=0;j<newitems.length;j++)
{
Bean bb = new Bean();
bb.setName(newitems[j]);
al.add(bb);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
runOnUiThread(new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
listView.invalidateViews();
}
});
swipeLayout.setRefreshing(false);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Bean.class
public class Bean {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Where i am making mistake?
This is the adapter that you're setting initially :
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,players);
Inside your doInBackground() method, you update the a1 ArrayList but your players Array on which the adapter depends remains the same hence no changes are reflected in the listview even when you do adapter.notifyDataSetChanged().
Secondly, the onPostExecute method runs on the ui thread so you do not need to do that explicitly.
I have a Activity in which when i click on refresh action bar icon it starts an async task. I have callbacks of async task in mainactity. in preexecute i am displaying progressbar on action bar and in postexecute i am displaying back refresh item. But when there is screen rotation after async task is started, onpostexecute runs but it is not calling invalidate options menu.
please help me out.
here is my MainActivity:
package in.cdac.enbee;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends Activity implements RefreshTask.TaskCallbacks {
// Our created menu to use
private Menu mymenu;
volatile static boolean isrefreshing=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d("Debug", "OncreateOptionsMenu");
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
// We should save our menu so we can use it to reset our updater.
mymenu = menu;
if(isrefreshing) {
menu.findItem(R.id.action_refresh).setActionView(R.layout.action_progressbar);
} else {
menu.findItem(R.id.action_refresh).setActionView(null);;
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch(item.getItemId()) {
case R.id.action_refresh:
// Do animation start
new RefreshTask(this).execute();
return true;
case R.id.action_settings:
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onSaveInstanceState (Bundle savedInstanceState) {
//Log.d("Debug", "OnSave");
//Always call superclass first
super.onSaveInstanceState(savedInstanceState);
// Restore value of members from saved state
//savedInstanceState.putBoolean("isRefreshing", isrefreshing);
}
#Override
protected void onRestoreInstanceState (Bundle savedInstanceState) {
//Log.d("Debug", "OnRestore");
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
// Restore value of members from saved state
//isrefreshing = savedInstanceState.getBoolean("isRefreshing");
} else {
// Probably initialize members with default values for a new instance
//isrefreshing = false;
}
}
#Override
public void onPreExecute() {
// TODO Auto-generated method stub
isrefreshing = true;
invalidateOptionsMenu();
}
#Override
public void onCancelled() {
// TODO Auto-generated method stub
isrefreshing = false;
invalidateOptionsMenu();
}
#Override
public void onPostExecute(Boolean done) {
// TODO Auto-generated method stub
isrefreshing = false;
if(done) {
Toast.makeText(this, "Done refreshing", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Downloading Failed", Toast.LENGTH_SHORT).show();
}
invalidateOptionsMenu();
}
}
and my async task:
package in.cdac.enbee;
import android.os.AsyncTask;
public class RefreshTask extends AsyncTask<Void, Void, Boolean> {
/**
*
*/
static interface TaskCallbacks {
void onPreExecute();
void onCancelled();
void onPostExecute(Boolean done);
}
private TaskCallbacks mCallbacks;
public RefreshTask(TaskCallbacks mCallbacks) {
this.mCallbacks = mCallbacks;
}
#Override
protected void onPreExecute() {
mCallbacks.onPreExecute();
}
#Override
protected void onCancelled() {
if (mCallbacks != null) {
mCallbacks.onCancelled();
}
}
#Override
protected Boolean doInBackground(Void... nope) {
try {
// Set a time to simulate a long update process.
Thread.sleep(4000);
return true;
} catch (Exception e) {
return false;
}
}
#Override
protected void onPostExecute(Boolean done) {
if (mCallbacks != null) {
mCallbacks.onPostExecute(done);
}
}
}
and my layout file for progressbar:
<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ProgressBar>
Thank you.
You are passing your Acitvity object to AsyncTask. This approach does not work. Basically android system can destroy and later recreate your activity at any time (one example is when orientation changes) and you have to be prepared for this situation.
What you are seeing now is that your code is being called but it uses old activity, not the one created after orientation change, so your code has no effect.
I do not know if this is the proper way or not, but I did have a little workaround and it works.
I am creating an reference to RefreshTask Async task in mainactivity. Initially making it null.
static RefreshTask rt=null;
then added a method in async task class.
public void updateobject(TaskCallbacks mCallbacks) {
this.mCallbacks = mCallbacks;
}
and in mainactivity, in onRestoreInstanceState, calling that method.
#Override
protected void onRestoreInstanceState (Bundle savedInstanceState) {
//Log.d("Debug", "OnRestore");
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
if(rt != null) {
rt.updateobject(this);
}
}
Please let me know what you think.
Also, suggest me an alternative way of doing it.