I try to do app which show elements. Each element should start showing when the before element was hidden. Each element is showing 2 seconds. I try a lot of way:
Android/java - How to do that loop wait to do action
And now I try with Asynctask. I find a way:
public class MainActivity extends Activity
{
ImageView image1,image2;
int id = 0;
AsyncTask.Status status;
TextView txt;
String status1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LongOperation task = new LongOperation();
status = task.getStatus();
status1 = String.valueOf(status);
txt = (TextView) findViewById(R.id.txt);
image1 = (ImageView)findViewById(R.id.image1);
image2 = (ImageView)findViewById(R.id.image2);
do{
new LongOperation().execute("");
id=id+1;
txt.setText(status1);
try
{
try
{
task.get(2500, TimeUnit.MILLISECONDS);
} catch (TimeoutException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}while(id<3);
}
private class LongOperation extends AsyncTask<String, Void, String>
{
#Override
protected void onPreExecute()
{
image1.setVisibility(View.VISIBLE);
image2.setVisibility(View.VISIBLE);
txt.setText(status1);
}
#Override
protected String doInBackground(String... params) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.interrupted();
}
return null;
}
#Override
protected void onPostExecute(String result) {
txt.setText("Executed");
image1.setVisibility(View.GONE);
image2.setVisibility(View.GONE);
}
#Override
protected void onProgressUpdate(Void... values) {}
}
(This is a example). App run and end after 7.5 sec (everything ok) but images aren't shown when I start. What should I do?
I think you are creating a deadlock situation with your threads. The main UI thread is blocking at the line task.get(), which in turn is preventing the AsyncTask from running properly; its onPreExecute method is posted onto the UI Thread, and the doInBackground doesn't run until onPreExecute completes.
Related
i have an asynctask but if i implement a Thread.Sleep , then my app crashes , i dont know why, in onPreExecute i can see my first message and then after two secs it appears the other one i put in doInBackground , but its not working
private class sendMail extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
dialog.setMessage("Please wait...");
dialog.show();
}
// automatically done on worker thread (separate from UI thread)
#Override
protected Void doInBackground(Void... voids) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
dialog.setMessage("Downloading files...");
new BackgroundTask().execute();
//MY DOWNLOADING METHODS STUFF
And then i dismiss this dialog somewhere else
Log
An error occurred while executing doInBackground()
You cannot access the UI elements from a background thread you can update the progressbar in onProgressUpdate, most importantly you need to publishProgress(value) in doInBackground and update using onProgressUpdate. Read more about the AsyncTask here.
Example code:
class MyTask extends AsyncTask<Integer, Integer, String> {
#Override
protected String doInBackground(Integer... params) {
for (; count <= params[0]; count++) {
try {
Thread.sleep(1000);
publishProgress(count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Task Completed.";
}
#Override
protected void onPostExecute(String result) {
progressBar.setVisibility(View.GONE);
txt.setText(result);
btn.setText("Restart");
}
#Override
protected void onPreExecute() {
txt.setText("Task Starting...");
}
#Override
protected void onProgressUpdate(Integer... values) {
txt.setText("Running..."+ values[0]);
progressBar.setMessage("Downloading files...");
progressBar.setProgress(values[0]);
}
}
Use UI thread to show dialog message in doInBackground refer this https://stackoverflow.com/a/15757788/6626966
i have an issue with an AsyncTask. I have an Activity with three CheckBox that if checked launch the async task when the user press the button. My async is this
private class MyTask extends AsyncTask<Void, Void, Void> {
String valore
public MyTask(String valore) {
this.valore = valore;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage(getString(R.string.message));
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
// Exec some operations
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if(risultato != null) {
textView.append(risultato);
}
if(errori != null) {
textView.append(errori);
}
progressDialog.dismiss();
}
}
And the button
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(checkBox.isChecked()) {
new MyTask("string").execute();
}
if(checkBox2.isChecked()) {
new MyTask("string2").execute();
}
if(checkBox3.isChecked()) {
new MyTask("string3").execute();
}
}
});
The problem is that if two or three checkbox are checked the ProgressDialog is not dismissed and remain on the screen. Why? How can i dismiss it also when two or more checkbox are checked?
try {
if ((pDialog != null) && pDialog.isShowing()) {
pDialog.dismiss();
}
} catch (final IllegalArgumentException e) {
// Handle or log or ignore
} catch (final Exception e) {
// Handle or log or ignore
} finally {
pDialog = null;
}
Try dismissing the dialog like this It might solve your problem
There are problem in this code
public void onClick(View v) {
// TODO Auto-generated method stub
if(checkBox.isChecked()) {
new MyTask("string").execute();
}
if(checkBox2.isChecked()) {
new MyTask("string2").execute();
}
if(checkBox3.isChecked()) {
new MyTask("string3").execute();
}
}
this is besically a logical error if we dry run this code it will
execute as many time as number of checked checkbox increases .
Suppose you do the checkbox1 to checked it will execute the async 1 time
while when you click checkbox2 it will execute checkbox1 async as well as checkbox2 async
and it be so on so change the condition on the button onclicklistner
Hi Since you are creating a new progressDialog every time therefore it is not getting dismissed. Create only one and keep variable at common place . For example
#Override
protected void onPreExecute() {
super.onPreExecute();
if(progressDialog!=null){
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage(getString(R.string.message));
progressDialog.setIndeterminate(true);
progressDialog.show();
}
}
What are you doing in "doInBackground" method please write that code as well.
And what is "risultato" and "errori" refer to.
Am getting exception when the user continuously clicking the button on which am calling the async task.
So is there any way to cancel the execution of first async task execution on second time pressing the button.
I hope u understand the problem.
The codes am using is given below.
On button click am using the following code
GetData obj= new GetData();
String urls="http://pathramonline.com/?cat=46";
obj.execute(urls);
My async task
public class GetData extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
BufferedReader reader =null;
String data =null;
try{
HttpClient client = new DefaultHttpClient();
URI uri=new URI(params[0]);
HttpGet get =new HttpGet(uri);
HttpResponse response= client.execute(get);
InputStream stream=response.getEntity().getContent();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer =new StringBuffer("");
String line="";
String newLine= System.getProperty("line.separator");
while((line=reader.readLine())!=null){
buffer.append(line+newLine);
}
reader.close();
data = buffer.toString();
return data;
}
catch(URISyntaxException e){
e.printStackTrace();
}
catch(ClientProtocolException f){
f.printStackTrace();
}
catch(IOException g){
g.printStackTrace();
}
catch(Exception e)
{
//
}
finally{
if(reader!=null){
try{
reader.close();
}
catch(Exception e){
}
}
}
return null;
}
#Override
protected void onCancelled() {
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//TextView t3=(TextView)findViewById(R.id.textView3);
if(result==null)
{
Intent home = new Intent(MainActivity.this,NoConnection.class);
MainActivity.this.startActivity(home);
MainActivity.this.finish();
}
//Some actions
}
}
I would suggest another method instead of cancelling the asynctask.
In your onPreExecute() method disable the button click
button.setEnabled(false);
And in onPostExecute() method enable back the button
button.setEnabled(true);
If you explicitly want to know that button is disabled then while the asynctask is being executed you can change the background color of the button to another color or background, so that the user will know that some function is being carried out and he needs to wait..
Another approach is
new AsyncTask<Void, Void, Void>() {
String result = "";
ProgressDialog progressDialog = null;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Loading , Please wait...");
progressDialog.setIndeterminate(true);
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
String url = "your link comes here"
JSONObject jsonObject = jpass.getJSONFromUrl(url);
try {
//do your work here
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void a) {
// TODO Auto-generated method stub
progressDialog.dismiss();
if (result.equals("success")) {
//on success do some work here
}
else
{
//on failure do some work here
}
super.onPostExecute(a);
}
}.execute();
Instead of cancelling the AsyncTask just set your button's click listener to null and then again set it inside onPostExecute of your AsyncTask. It would be even better if you display a ProgressBar when your doInBackground() code is executing.
I Can't use findViewById() from my Kclass=( How can i use it? `
private class BackGroundTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
try {
//execute - means sending
response =httpClient.execute(request);
HttpEntity entity=response.getEntity();
String str=EntityUtils.toString(entity);
Log.v("Json=", str);
//adding new response to our Response Class
resp.addNewResponse(str);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
Log.e(TAG, "Exception caught: ", e);
}
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
httpClient.getConnectionManager().shutdown();
TextView textView = (TextView) findViewById(R.id.textView1);
textView.setText("Done");
}
}
}
please write an exact code. This class is in another .java file. Not in MainActivity.java
The easiest way would be to not use findViewById() at all since you are in a separate file and that is an Activity method.
You can simply use an interface to create a callback in onPostExecute() and send back the String result to your Activity. Then in your callback you can simply set the text as you wish.
This answer gives an example of using an interface with AsyncTask
You may pass Activity context(YourActivity.this) to your AsyncTask and use activity.findViewById(...);
EDIT
Some code:
Add to AsyncTask:
private Activity mActivity;
public YourAsyncTask(Activity activity){
this.mActivity = activity
}
...
....
protected void onPostExecute(Void result) {
super.onPostExecute(result);
httpClient.getConnectionManager().shutdown();
if(mActivity!=null){
TextView textView = (TextView) mActivity.findViewById(R.id.textView1);
}
textView.setText("Done");
}
private Activity activity;
and in constructor:
public BackGroundTask(Activity activity){
this.activity=activity;
}
and in post Execute:
protected void onPostExecute(Void result) {
super.onPostExecute(result);
httpClient.getConnectionManager().shutdown();
TextView textView = (TextView) activity.findViewById(R.id.textView1);
textView.setText("Done");
}
If creating new background class from activity class call:
BackGroundTask doItInBackGround = new BackGroundTask(this);
If in a click listener or any class inside Activity call:
BackGroundTask doItInBackGround = new BackGroundTask(ActivityName.this);
I have the following class:
class CargaImgsParaAmpliar extends AsyncTask<Void, Void, Bitmap> {
final ProgressDialog progressDialog = new ProgressDialog(imagen.this);
protected void onPreExecute() {
progressDialog.setTitle("");
progressDialog.setMessage("Cargando Imagen...");
progressDialog.show();
}
protected Bitmap doInBackground(Void... params) {
Bitmap mIcon1 = null;
URL url_value;
try {
url_value = new URL(StrUrl);
mIcon1 = BitmapFactory.decodeStream(url_value.openConnection().getInputStream());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mIcon1;
}
protected void onPostExecute(Bitmap imagen) {
m_imageView.setImageBitmap(urlImageToBitmap(StrUrl));
progressDialog.dismiss();
}
}
I am doing internet discharge processes within AsyncTask and it still gives me the exception android.os.NetworkOnMainThreadException.
How can I fix this isse?
It seems to me that urlImageToBitmap accesses the network but is executed from onPostExecute (which is run on the UI task).
And you don't seem to be doing anything with imagen parameter in onPostExecute. So the image retrieved in doInBackground is basically lost.