How would I call this function in asynctask?
void somefunc()
{
tr1 = (TableRow) new TableRow(this);
//error
txt1=new TextView(this);
txt9.setText(strinarr[0]);
tr1.addView(txt1);
tl.addView(tr1,new TableLayout.LayoutParams(layoutParams));
}
class SaveAdDetail extends AsyncTask<Void, String, Void>
{
#Override
public void onPreExecute()
{
super.onPreExecute();
Progdialog = ProgressDialog.show(demotable.this, "", "Please Wait...", true);
Progdialog.show();
}
#Override
public Void doInBackground(Void... unused)
{
try
{somefunc();}
catch (Exception e)
{strdata="Error";}
return null;
}
#Override
public void onPostExecute(Void unused)
{
Progdialog.dismiss();
if(strdata.equals("Error"))
{Toast(strdata);}
else
{
Toast("asdasdasd");
}
}
}
You have a choice : use handlers or call directly. In both cases you should pass a reference to the constructor of AsyncTask. onPostExecute() is called on the UI thread, so you can call the method directly on the reference of your activity.
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.TASK_FINISHED:
somefunc();
break;
}
}
};
SaveAdDetail task = new SaveAdDetail(handler);
task.execute();
// in your SaveAdDetail:
#Override
public void onPostExecute(Void unused) {
Progdialog.dismiss();
handler.obtainMessage(Constants.TASK_FINISHED).sendToTarget();
}
I would use a Handler. Here is an example: http://developer.android.com/resources/articles/timed-ui-updates.html
Related
Here is my main Activity in OnCreate:
mUnityPlayer = new UnityPlayer(this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
new SimuDownloadTask(this).execute();
The following code is the source code of SimuDownloadTask:
public class SimuDownloadTask extends AsyncTask<Void, Integer, Boolean> {
private ProgressDialog progressDialog;
private int count=0;
private Context mainActivityContext;
public SimuDownloadTask(Context context) {
mainActivityContext=context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog=new ProgressDialog(mainActivityContext,R.style.XMNewDialog);
progressDialog.show();
}
#Override
protected Boolean doInBackground(Void... arg0) {
while(true)
{
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int downloadPercent=doDownload();
publishProgress(downloadPercent);
if(downloadPercent>=500)
break;
}
return true;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressDialog.setMessage("current progress:"+values[0]+"%");
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressDialog.dismiss();
if(result)
{
Toast.makeText(mainActivityContext, "success", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(mainActivityContext, "fail", Toast.LENGTH_SHORT).show();
}
}
private int doDownload()
{
count+=1;
return count;
}
}
Here is the problem. When I start the app, the progressbar blocks the UI thread.
After the progressbar finished, the Unity starts.
When I replace the SimuDownloadTask in OnCreate with the following code:
new Thread(){
#Override
public void run() {
super.run();
Looper.prepare();
progressDialog=new ProgressDialog(UnityPlayerActivity.this,R.style.XMNewDialog);
progressDialog.setTitle("test");
progressDialog.setCancelable(true);
progressDialog.show();
Looper.loop();
}
}.start();
The unity thread is running properly(not blocked by the progressbar). So I think the problem is not relevant to Unity.
I have already checked the relevant links such as:
Asynctask from non ui thread
But still can't figure out the issues.
Any clues will be helpful.
Instead of using an AsyncTask you may use a worker thread for the counter logic and a handler to update the progress bar.
See the updated answer in this link
I am new to android programming. I am developing a web crawler for which i am using a Async Task and it is working well.In order to keep user informed,i am using progress dialog. My problem is,if i use a Progress Dialog my program takes more time to execute and when i won`t use the progress dialog,it executes faster.
Done Work
OnCreate Method
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_results);
Intent intent = getIntent();
s1 = intent.getStringExtra("Number1");
s2 = intent.getStringExtra("Number2");
s3=intent.getIntExtra("selectedItem",0);
HttpAsyncTask asyncTask = new HttpAsyncTask();
asyncTask.execute();
}catch (Exception e)
{
messageBox("Exception",e.getMessage());
}
}
Async Task Class
private class HttpAsyncTask extends AsyncTask<List<String>, Integer, List<String>> {
private ProgressDialog dialog;
#Override
protected void onPreExecute()
{
dialog = new ProgressDialog(Results.this);
dialog.setIndeterminate(true);
dialog.setMessage("Please Wait");
dialog.setCancelable(true);
dialog.show();
super.onPreExecute();
}
#Override
protected List<String> doInBackground(List<String>... urls) {
//android.os.Debug.waitForDebugger();
// spinner.setVisibility(View.VISIBLE);
List<String>resultList=new ArrayList<String>();
try
{
if(isCancelled())
return resultList;
resultList=WebCrawlerClass.GetPost(s1,s2,s3);
}catch (Exception e)
{
messageBoxs("Error", e.getMessage());
}
return resultList;
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(List<String> result)
{
if(dialog.isShowing())
{
dialog.dismiss();
}
if(s3 == 2)
{
docListAdapter=new ListViewData(Results.this,result);
}
else {
docListAdapter = new NameNumListData(Results.this, result);
}
docList=(ListView)findViewById(R.id.listView2);
docList.setAdapter(docListAdapter);
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
super.onCancelled();
this.cancel(true);
}
}
Am I missing something? Need help..
Thanks and Regards,
Abhinav
In you activity
// Start the progress dialog
..
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// dismiss the progress dialog
}
};
HttpAsyncTask asyncTask = new HttpAsyncTask(handler);
asyncTask.execute();
In your asynctask class
private class HttpAsyncTask extends AsyncTask<List<String>, Integer, List<String>> {
private Handler handler = null;
public HttpAsyncTask (Handler handler) {
this.handler = handler;
}
protected Void doInBackground(Void... params) {
//Perform your task
// When you know that task is finished , fire following code
if (null != handler) {
Message message = handler.obtainMessage();
message.obj = Any data you want to sent to the activity
message.what = 1 ; ( Optional )
handler.sendMessage(message);
}
}
Thus when sendMessage function is called from doInbackground.. your handleMessage in your activity will get triggered and then you should dismiss the progress dialog
Hope this will improve the performance issue what you are facing
Remove super.onPreExecute(); in onPreExecute() method and check .It might Help
I am trying to put a progressDialog in my fragment so my app feels smoother between each actions. The problem that I have is that the main thread is returning the view before the async thread has modified it. I was doing a Thread.join() before switching to this methode.
public class MyFragment extends Fragment {
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle args) {
mLLayout = new LinearLayout(getActivity());
mLLayout.setPadding(0, 0, 0, 0);
mLLayout.setOrientation(LinearLayout.VERTICAL);
mScroll = new ScrollView(getActivity().getApplicationContext());
mScroll.setVerticalScrollBarEnabled(true);
mScroll.addView(mLLayout);
new AsyncCaller().execute();
return mScroll;
}
private class AsyncCaller extends AsyncTask<Void, Void, Void>
{
ProgressDialog nDialog = new ProgressDialog(getActivity());
#Override
protected void onPreExecute()
{
super.onPreExecute();
//this method will be running on UI thread
nDialog = new ProgressDialog(getActivity());
nDialog.setMessage("Loading..");
nDialog.setTitle("Checking Network");
nDialog.setIndeterminate(false);
nDialog.setCancelable(true);
nDialog.show();
}
#Override
protected Void doInBackground(Void... params)
{
//Doing http requests and modifying views
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
//this method will be running on UI thread
nDialog.dismiss();
}
}
...
}
I cant find a solution without blocking the main thread and by the same way not seeing the progressDialog at all and having a big lag instead. Also, I never saw my code go into "onPostExecute()".
Thanks in advance for your help!
Striaght from an app i've done, this code should help:
ProgressBar mProgress = (ProgressBar) findViewById(R.id.progressBar);
private float mProgressStatus = 0;
private Handler mHandler = new Handler();
private void startProgressBar()
{
new Thread(new Runnable()
{
#Override
public void run()
{
while (mProgressStatus < 100)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
mProgressStatus += 1.3;
mHandler.post(new Runnable()
{
#Override
public void run()
{
mProgress.setProgress((int) mProgressStatus);
}
});
}
}
}).start();
}
In my app ,there is an one button which get input from database.When I press it more than one in a short time it crashes.
How can i avoid this error with using asynctask?
show.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
showinf();
}
});
}
private String[] columns={"name","surname"};
private void showinf(){
SQLiteDatabase db=v1.getReadableDatabase();
Cursor c=db.query("infos",columns,null,null, null,null,null);
Random mn2=new Random();
int count=c.getCount();
String mn=String.valueOf(count);
int i1=mn2.nextInt(count+1);
c.move(i1);
t1.setText(c.getString(c.getColumnIndex("name")));
t2.setText(c.getString(c.getColumnIndex("surname")));
}
thanks...
You can create a boolean flag (let's say bDiscardButtonAction), and set it to true in onPreExecute() and set it to false in onPostExecute(), something like:
public class FooTask extends AsyncTask<Foo, Foo, Foo>
{
private static boolean bDiscardButtonAction = false;
private boolean isDiscareded = false;
#Override
public void onPreExecute()
{
if(bDiscardButtonAction)
{
isDiscareded = true;
return;
}
bDiscardButtonAction = true;
}
#Override
public Foo doInBackground(Foo... params)
{
if(isDiscareded) return;
// ...
}
#Override
public void onPostExecute(Void result)
{
if(!isDiscareded) bDiscardButtonAction = false;
}
#Override
public void onCancelled(Foo result)
{
if(!isDiscareded) bDiscardButtonAction = false;
}
}
disable the show button in onPreExecute() and enable it back onPostExecute().
public class getAsyncDataTask extends AsyncTask<Void, Void, Void>
{
#Override
public void onPreExecute()
{
show.setAlpha(0.5);
show.setEnable(false);
}
#Override
public void doInBackground(Void... params)
{
//retrieve the data from db;
}
#Override
public void onPostExecute()
{
show.setAlpha(1.0);
show.setEnable(true);
}
}
I hope this code will help u out.
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
new AsynchTaskManualLocation().execute();
});
public class AsynchTaskGetData extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... url) {
//showinf(); this method contains operation of getting data from //database OR ur logic to getdata
return showinf();
}
#Override
protected void onPostExecute(String result) {
//here u get result in resul var and process the result here
}
}
}
I get this error "Can't create handler inside thread that has not called Looper.prepare()"
Can you tell me how to fix it?
public class PaymentActivity extends BaseActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.payment);
final Button buttonBank = (Button) findViewById(R.id.buttonBank);
buttonBank.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
progressDialog = ProgressDialog.show(PaymentActivity.this, "",
"Redirecting to payment gateway...", true, true);
new Thread() {
public void run() {
try {
startPayment("Bank");
} catch (Exception e) {
alertDialog.setMessage(e.getMessage());
handler.sendEmptyMessage(1);
progressDialog.cancel();
}
}
}.start();
}
});
StartPayment Method:
private void startPayment(String id) {
Bundle b = getIntent().getExtras();
final Sail sail = b.getParcelable(Constant.SAIL);
final Intent bankIntent = new Intent(this, BankActivity.class);
try {
Reservation reservation = RestService.createReservation(
sail.getId(),
getSharedPreferences(Constant.PREF_NAME_CONTACT, 0));
bankIntent.putExtra(Constant.RESERVATION, reservation);
// <workingWithDB> Storing Reservation info in Database
DBAdapter db = new DBAdapter(this);
db.open();
#SuppressWarnings("unused")
long rowid;
rowid = db.insertRow(sail.getId(), sail.getFrom(),
sail.getTo(), sail.getShip(), sail.getDateFrom().getTime(),
sail.getPrice().toString(), reservation.getId().floatValue());
db.close();
// </workingWithDB>
String html = PaymentService.getRedirectHTML(id, reservation);
bankIntent.putExtra(Constant.BANK, html);
} catch (Exception e) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alertDialog = builder.create();
alertDialog.setMessage(e.getMessage());
alertDialog.show();
}
startActivity(bankIntent);
}
You should know that when you try to modify your UI , the only thread who can do that is the UiThread.
So if you want to modify your UI in another thread, try to use the method: Activity.runOnUiThread(new Runnable);
Your code should be like this :
new Thread() {
public void run() {
YourActivity.this.runOnUiThread(new Runnable(){
#Override
public void run(){
try {
startPayment("Bank");//Edit,integrate this on the runOnUiThread
} catch (Exception e) {
alertDialog.setMessage(e.getMessage());
handler.sendEmptyMessage(1);
progressDialog.cancel();
}
});
}
}
}.start();
I assume you create a Handler in startPayment() method. You can't do that, as handlers can be created on th UI thread only. Just create it in your activity class.
Instead of new Thread() line, try giving
this.runOnUiThread(new Runnable() {
you cant change any UI in thread you can use runOnUIThread or AsyncTask for more detail about this click here
I've found that most thread handling can be replaced by AsyncTasks like this:
public class TestStuff extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonBank = (Button) findViewById(R.id.button);
buttonBank.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new StartPaymentAsyncTask(TestStuff.this).execute((Void []) null);
}
});
}
private class StartPaymentAsyncTask extends AsyncTask<Void, Void, String> {
private ProgressDialog dialog;
private final Context context;
public StartPaymentAsyncTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(context);
// setup your dialog here
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage(context.getString(R.string.doing_db_work));
dialog.setCancelable(false);
dialog.show();
}
#Override
protected String doInBackground(Void... ignored) {
String returnMessage = null;
try {
startPayment("Bank");
} catch (Exception e) {
returnMessage = e.getMessage();
}
return returnMessage;
}
#Override
protected void onPostExecute(String message) {
dialog.dismiss();
if (message != null) {
// process the error (show alert etc)
Log.e("StartPaymentAsyncTask", String.format("I received an error: %s", message));
} else {
Log.i("StartPaymentAsyncTask", "No problems");
}
}
}
public void startPayment(String string) throws Exception {
SystemClock.sleep(2000); // pause for 2 seconds for dialog
Log.i("PaymentStuff", "I am pretending to do some work");
throw new Exception("Oh dear, database error");
}
}
I pass in the Application Context to the Async so it can create dialogs from it.
The advantage of doing it this way is you know exactly which methods are run in your UI and which are in a separate background thread. Your main UI thread isn't delayed, and the separation into small async tasks is quite nice.
The code assumes your startPayment() method does nothing with the UI, and if it does, move it into the onPostExecute of the AsyncTask so it's done in the UI thread.
Try
final Handler handlerTimer = new Handler(Looper.getMainLooper());
handlerTimer.postDelayed(new Runnable() {
public void run() {
......
}
}, time_interval});