I am using AsyncTask and fetch twitter feed asynchronously to display in a listView. It works fine Then for refreshing the listview I put the asyncTask call into a Runnable's Run() to load it after a specific interval. The feed loads after specific time interval but the listview is not updating. I use notifyDataSetChanged() inside the asyncTask but it is not working.
This is my trying code:
public class Twitter7FeedActivity extends Activity {
LazyAdapter adapter;
ListView list;
JSONObject jsonObj = null;
JSONArray jsonArray = null;
#SuppressLint("SimpleDateFormat")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_twitter7_feed);
callAsynchronousTask();
}
public void callAsynchronousTask() {
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
new GetFeedTask().execute(CommonUtils.BEARER_TOKEN,
CommonUtils.URL);
} catch (Exception e) {
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 50000);
}
protected class GetFeedTask extends AsyncTask<String, Void, String> {
private ProgressDialog dialog = new ProgressDialog(
Twitter7FeedActivity.this);
protected void onPreExecute() {
this.dialog.setMessage("Please wait");
this.dialog.show();
}
#Override
protected String doInBackground(String... params) {
// related code
}
#Override
protected void onPostExecute(String jsonText) {
// related code
adapter = new LazyAdapter(Twitter7FeedActivity.this,
// tweets);
list = (ListView) findViewById(R.id.list);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
}
Have you tried moving this line:
list = (ListView) findViewById(R.id.list);
after your setContentView in your onCreate method?
// related code adapter = new LazyAdapter(Twitter7FeedActivity.this, tweets);
uncomment this code which is in onPostExecute() method. I think it may help you out. thanks...
You can do the work mentioned in your question using only a Handler. Something like this:
public class Twitter7FeedActivity extends Activity {
LazyAdapter adapter;
ListView list;
JSONObject jsonObj = null;
JSONArray jsonArray = null;
#SuppressLint("SimpleDateFormat")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_twitter7_feed);
callAsynchronousTask();
}
public void callAsynchronousTask() {
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
ProgressDialog dialog;
public void run() {
try {
//Show your dialog here
runOnUiThread(new Runnable() {
public void run() {
runnable.this.dialog = new ProgressDialog( Twitter7FeedActivity.this);
runnable.this.dialog.setMessage("Please wait");
runnable.this.dialog.show();
}
});
//Do your AsyncTask's doInBackground work here
//Update the UI with runOnUiThread or using the Ui threa handler
runOnUiThread(new Runnable() {
public void run() {
// related code adapter = new LazyAdapter(Twitter7FeedActivity.this, tweets);
list = (ListView) findViewById(R.id.list);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
});
//Then post the thread to excecute after 50000 milliseconds.
handler.postDelayed(runnable, 50000);
} catch (Exception e)
{ }
}
};
handler.post(runnable);
}
}
This way you avoid using an AsyncTask inside a TimerTask.
Related
I have the MainActivity as this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bo = new Operation(getApplicationContext());
}
public void op_perform(View v) throws Exception { //call this when a button is pressed
try {
bo.demo();
} catch (Exception e) {
// TODO: handle exception
}
The Operation class has the following lines of code:
Context con;
Operation(Context ac) {
con = ac;
barProgressDialog = new ProgressDialog(con);
updateBarHandler = new Handler();
}
public void demo() {
barProgressDialog = new ProgressDialog(con);
barProgressDialog.setTitle("Downloading Image ...");
barProgressDialog.setMessage("Download in progress ...");
barProgressDialog.setProgressStyle(barProgressDialog.STYLE_HORIZONTAL);
barProgressDialog.setProgress(0);
barProgressDialog.setMax(20);
barProgressDialog.show();
...
But, i'm not getting the progress dialog at all in my screen. I want the progress dialog to be a determinate horizontal one. This is just a piece of code and i need to put these in the Asyn task. But the processdialog is not even showing. Recommended solutions. I'm a beginner to android.
Here is a complete example of what you need: http://turboprogramacion.blogspot.cl
private ProgressDialog barraProgreso;
private Handler handler;
private void mostrarBarraProgreso(){
barraProgreso = new ProgressDialog(MainActivity.this);
barraProgreso.setTitle("Buscando...");
barraProgreso.setMessage("Progreso...");
barraProgreso.setProgressStyle(barraProgreso.STYLE_HORIZONTAL);
barraProgreso.setProgress(0);
barraProgreso.setMax(10);
barraProgreso.show();
handler = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
try {
while (barraProgreso.getProgress() <= barraProgreso.getMax()) {
Thread.sleep(1000);
handler.post(new Runnable() {
#Override
public void run() {
barraProgreso.incrementProgressBy(1);
}
});
if(barraProgreso.getProgress() == barraProgreso.getMax()){
barraProgreso.dismiss();
}
}
}catch (InterruptedException er){
er.printStackTrace();
}
}
}).start();
}
Below is my code that is not working and i dont understand why it says "Only the original thread that created a view hierarchy can touch its views." when i want to set the adapter for my listview inside LoadValues() method.. "listView.setAdapter(adapter)"
public class ProgressDialogActivity extends Activity {
private ProgressDialog progressDialog;
private ListView listView;
private ArrayList<String> lstValores;
private Handler progressBarHandler = new Handler();
private int mProgressStatus, mProgressTotal;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lstValores = new ArrayList<String>();
listView = (ListView) findViewById(R.id.listView1);
this.LoadValues();
}//onCreate
public void LoadValues(){
progressDialog = new ProgressDialog(ProgressDialogActivity.this);
progressDialog.setTitle("Aguarde..");
progressDialog.setMessage("Cargando lista..");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setProgress(0);
progressDialog.show();
new Thread(new Runnable() {
public void run() {
mProgressTotal = (int) 1000;
try {
for (int i = 0; i < mProgressTotal; i++) {
lstValores.add("valor " + i);
mProgressStatus = (int) ((i * 100) / mProgressTotal);
progressBarHandler.post(new Runnable() {
public void run() {
progressDialog.setProgress(mProgressStatus);
}
});
}// end for
ArrayAdapter<String> adapter = new ArrayAdapter<String>(ProgressDialogActivity.this,
R.layout.textviewlist_layout,
lstValores);
listView.setAdapter(adapter);
progressDialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}// end run
}).start();// end Thread
}// end LoadValues
} // Activity
In android, Only the UI Thread can touch the View.
So
progressBarHandler.post(new Runnable() {
public void run(){
listView.setAdapter(adapter);
}
}
I am building a project in which i use async task to show progress bar.
I am using get() method to wait the main thread so we can do the other task before .
but progress bar is showing after completion of doInBackground thered.
I Want to show the loading bar when the loading starts.
It will dismiss when onPostExecute calls.
public class TempConverterActivity extends Activity {
pojo p;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b= (Button) findViewById(R.id.btn);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showResult();
}
});
}
private void showResult() {
try {
new LoadData().execute().get();
} catch (Exception e) {
Log.e("async brix--", e.getMessage());
}
runned();
}
private void runned() {
ArrayList<String> al = p.getData();
for (String str : al){
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
}
}
private class LoadData extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(TempConverterActivity.this);
protected void onPreExecute() {
dialog.setMessage("Loading data...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
protected void onPostExecute(final Void unused) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
#Override
protected Void doInBackground(Void... params) {
p = new pojo();
new SoapParser(p);
return null;
}
}}
Please help . Thanks in advance.
You can try following code,
progDailog = ProgressDialog.show(loginAct,"Process ", "please wait....",true,true);
new Thread ( new Runnable()
{
public void run()
{
// your code goes here
}
}).start();
Handler progressHandler = new Handler()
{
public void handleMessage(Message msg1)
{
progDailog.dismiss();
}
}
Edited: In my previous answer I suggested using a Handler; however, AsyncTask eliminates the need to do this which I didn't spot.
Why do you feel the need to call AsyncTask.get()? This is a blocking call, and you call this from the UI thread, thus it is ultimately a race condition as to whether it or onPreExecute() is run first.
I see no reason why you should call get() in this context. You want to call runned() after the AsyncTask completes, but you could do this by launching a new thread from onPostExecute(). Alternatively you could do as you do now, using get(), but call that from a new thread instead of the UI thread.
I am parsing an XML from a URL and showing it. I want to show ProgressDialog while my XML Parser Method parse the XML and get it ready to show. The problem I am facing is that no data is shown after ProgressDialog rather it shows blank screen.
Here is my code:
ArrayList<XMLItem> items= new ArrayList<XMLItem>();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mydata);
adapter= new MyAdapter(this, R.layout.customcell, items);
listView= (ListView) findViewById(id.ListView01);
listView.setAdapter(adapter);
final ProgressDialog dialog = ProgressDialog.show(this, "", "Loading. Please wait...", true);
Thread thread=new Thread(new Runnable(){
public void run(){
doTheAutoRefresh();
runOnUiThread(new Runnable(){
public void run() {
if(dialog.isShowing())
dialog.dismiss();
adapter.notifyDataSetChanged(); //this line throws an exception and if i comment this line, blank screen is shown
}
});
}
});
thread.start();
}
private void doTheAutoRefresh() {
handler.postDelayed(new Runnable() {
public void run(){
loadData(); // this is where you put your refresh code
doTheAutoRefresh();
}
}, 15000);
}
private void loadData(){
Document doc;
try {
doc = XMLReader.parseURL("my url to parse xml");
NodeList nl = doc.getElementsByTagName("l");
for(int i=0; i<nl.getLength(); i++){
NamedNodeMap np = nl.item(i).getAttributes();
String t= np.getNamedItem("htn").getNodeValue();
String sT= np.getNamedItem("atn").getNodeValue();
XMLItem item= new XMLItem(t, sT);
items.add(item);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This code shows ProgressDialog perfectly, but after progress dialog, it shows blank screen. Please help me sorting out this problem.
Thanks
private class xyz extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(tranning.this);
#Override
protected void onPreExecute() {
this.dialog.setMessage("Please Wait...");
this.dialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// do your load data function part here.
// just populate the data structures that are necessary
// for the adapter.
return null;
}
#Override
protected void onPostExecute(final Void unused) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
// notify adapter here.
adapter.notifyDataSetChanged();
refreshTimer(); // to do the same thing after 15 seconds.
}
}
}
now call the asycTask for the first time in your onCreate() probably.
new xyz().execute()
make a function to put a timer for refresh, we do that by using postDelayed.
private void refreshTimer(){
handler.postDelayed( runner , 15000);
}
private Runnable runner = new Runnable(){
public void run(){
new xyz().execute();
}
}
i think you need to implement AsyncTask ::
private class xyz extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(tranning.this);
#Override
protected void onPreExecute() {
this.dialog.setMessage("Please Wait...");
this.dialog.show();
// put your code which preload with processDialog
}
#Override
protected Void doInBackground(Void... arg0) {
// put your code here
return null;
}
#Override
protected void onPostExecute(final Void unused) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
and use this in main ::
new xyz().execute();
add a function showData() and call it after dismissing the dialog
ArrayList<XMLItem> items= new ArrayList<XMLItem>();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mydata);
listView= (ListView) findViewById(id.ListView01);
final ProgressDialog dialog = ProgressDialog.show(this, "", "Loading. Please wait...", true);
Thread thread=new Thread(new Runnable(){
public void run(){
loadData();
runOnUiThread(new Runnable(){
public void run() {
if(dialog.isShowing()){
dialog.dismiss();
showData(); //////////////////////////////////////
}
}
});
}
});
thread.start();
}
private void showData(){
adapter= new MyAdapter(this, R.layout.customcell, items);
listView.setAdapter(adapter);
}
private void loadData(){
Document doc;
try {
doc = XMLReader.parseURL("my url to parse xml");
NodeList nl = doc.getElementsByTagName("l");
for(int i=0; i<nl.getLength(); i++){
NamedNodeMap np = nl.item(i).getAttributes();
String t= np.getNamedItem("htn").getNodeValue();
String sT= np.getNamedItem("atn").getNodeValue();
XMLItem item= new XMLItem(t, sT);
items.add(item);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
progress dialog doesnt work while listing data with listAdapter
i think its all about sending activity to myAdapter
final myAdapter adapter = new myAdapter(rss_list_activity.this, liste);
final ProgressDialog dialog = ProgressDialog.show(this, "Title",
"Message", true);
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
dialog.dismiss();
}
};
Thread checkUpdate = new Thread() {
public void run() {
getListFromXml();
lv.setAdapter(adapter);
handler.sendEmptyMessage(0);
}
};
checkUpdate.start();
here's some information on threading, i would use an AsyncTask if I were you:
http://developer.android.com/resources/articles/painless-threading.html
Something similar to this should work:
LoadListTask tsk = new LoadListTask();
tsk.execute((Void) null);
with this somewhere
private class LoadListTask extends AsyncTask<Void, Void, List<theType>>
{
final ProgressDialog dialog;
#Override
protected void onPreExecute()
{
super.onPreExecute();
dialog = ProgressDialog.show(MainClass.this, "Title", "Message", true);
}
#Override
protected void onPostExecute(List<theType> result)
{
super.onPostExecute(result);
final myAdapter adapter = new myAdapter(rss_list_activity.this, result);
lv.setAdapter(adapter);
dialog.dismiss();
}
#Override
protected List<theType> doInBackground(Void... params)
{
return getListFromXml();
}
}
use dialog.show(); to show dialog. you are directly dismissing the dialog using dialog.dismiss();