0

I saw many dublicates of this questions ( here , here , here and here ) but i did not get solution for my problem.

This is my app's idea

Fetching contents from url and display it using textview on each button click.

(URL content will randomly generate different text for each refresh)


This is my old code of my app which worked perfectly but StackOverflow people advised me to use AsyncTask

I specified fetching URL contents operation in doInBackground() method and called new myAsyncTask.execute() in Button Click Event from onCreate.

It worked only for first click , and then my app crashed. It says AsyncTask should be called only once. But i want my TextView to be updated on each button click event.


So, What should i do now

Do I want to cancel my previous AsyncTask and call new one (or) I want to initialize new object for AsyncTask and call it again (which is the worst method)

How do i implement my idea in my app using AsyncTask or any Alternate?

This is my code:

public class MainActivity extends AppCompatActivity {

    TextView resultView;String TAG="MainActivity kbt";
    SmoothProgressBar mProgressBar;
    Context context;
    MyAsyncTask myAsyncTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      //  StrictMode.enableDefaults();  //Used to executes URL connection on MainThread without getting Exception
        setContentView(R.layout.activity_main);
        mProgressBar = (SmoothProgressBar) findViewById(R.id.progressBar);
       StrictMode.enableDefaults();
        resultView = (TextView) findViewById(R.id.result);
        myAsyncTask=new MyAsyncTask();
       // mProgressBar.setVisibility(SmoothProgressBar.INVISIBLE);


        Button insert=(Button) findViewById(R.id.button);
        insert.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                // TODO Auto-generated method stub
                myAsyncTask.execute();

            }
        });
    }   

    private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
        String mTAG = "myAsyncTask";

        @Override
        protected void onPreExecute() {
           mProgressBar.progressiveStart();
        }

        @Override
        protected Void doInBackground(Void... arg) {

            try {
                getData();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }


        @Override
        protected void onPostExecute(Void a) {
            mProgressBar.progressiveStop();
        }
    }

 public void getData() throws IOException {

        String result = "";
        InputStream isr = null;  

        URLConnection urlConnection = null;
        URL url = new URL("http://kbtganesh.16mb.com/index.php");
        Log.d(TAG,"After  URL NOT WORKING");   //AFTER THIS.... NEXT LOG (ie GOT URL CONNETION) IS NOT PRINTED

        urlConnection =  url.openConnection();

        Log.d(TAG, "GOT URL CONNETION");

        Log.d(TAG, "GOT URL CONNECTED");
        isr =urlConnection.getInputStream();
        Log.d(TAG,"AFTER ISR EQ");



        //convert response to string

        try {
           // BufferedReader reader = new BufferedReader(new InputStreamReader(isr,"iso-8859-1"),8);
            BufferedReader reader = new BufferedReader(new InputStreamReader(isr));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            isr.close();

            result=sb.toString();
        }
        catch(Exception e){
            Log.e("log_tag", "Error converting result "+e.toString());
        }

        //parse json data
        try {
            resultView.setText(result);
        }
        catch(Exception e) {
            Log.e("log_tag", "Couldn't set text, damnit.");
        }

    }

}

Thanks in advance... (:

Community
  • 1
  • 1
Ganesh
  • 1,820
  • 2
  • 20
  • 40
  • 1
    Just create a new instance of the AsyncTask each time you want to run it. If you can't get that to work, you'll have to post your code for us to help you. – Mike M. Dec 17 '15 at 10:32
  • post your code to help. – Amol Sawant Dec 17 '15 at 10:35
  • Yes i did, sorry i forget to paste it before – Ganesh Dec 17 '15 at 10:36
  • Move `myAsyncTask=new MyAsyncTask();` to the beginning of the `onClick()` method. – Mike M. Dec 17 '15 at 10:37
  • Please ignore `comments` and `LogCat` messages as i copied codes from various places. – Ganesh Dec 17 '15 at 10:37
  • change code on onClick of button from myAsyncTask.execute(); to new MyAsyncTask().execute(); – virendrao Dec 17 '15 at 10:38
  • @MikeM. It will then create instance and threads each time of button clicks. it will create even 100 instances if i click 100 times – Ganesh Dec 17 '15 at 10:39
  • Yep. If you want to run an AsyncTask a hundred times, you have to create a hundred instances. – Mike M. Dec 17 '15 at 10:40
  • @MikeM. it will create waste memory spaces and slow down the mobile phone, isn't it? Correct me if i am wrong? – Ganesh Dec 17 '15 at 10:42
  • is it good practice? – Ganesh Dec 17 '15 at 10:44
  • The AsyncTask instances will eventually be garbage-collected after they're done executing. Even if you were to do this some alternate way - like in an IntentService - it would still be doing the same basic thing; creating a new thread to handle each network transaction. – Mike M. Dec 17 '15 at 10:46
  • @MikeM. I never know that they will be garbage collected after they're done executing. Fine then, i'll follow your method. Thanks mate.. :) – Ganesh Dec 17 '15 at 10:47
  • btw, shall i delete this useless question ? :-\ – Ganesh Dec 17 '15 at 10:48

5 Answers5

6

Finally i got solution for my question with the help of StackOverflow friends.

Moving myAsyncTask=new MyAsyncTask(); inside onClick() method solved my problem. This is the best way to execute AsyncTask multiple times.

The AsyncTask instances will eventually be garbage-collected after they're done executing.Hence we don't need to worry about creation of multiple instances. They will be garbaged automatically.

MyAsyncTask myAsyncTask;
insert.setOnClickListener(new View.OnClickListener() {

        @Override 
        public void onClick(View view) {
            // TODO Auto-generated method stub 
            myAsyncTask=new MyAsyncTask();
            // TODO Auto-generated method stub
           myAsyncTask.execute();


        } 
    }); 
Ganesh
  • 1,820
  • 2
  • 20
  • 40
2

I saw your old post where you have used StrictMode.enableDefaults(); . Also said by Emmie Capps.

I can accept that app will not crash but it is better to use AsyncTask for many reasons. You can implement progressbar easily to indicate the process going in background and etc.

Simply initiating the instance inside your onClick() will be the better way.

Krish
  • 21
  • 2
1

You cannot execute the same instance of AsyncTask multiple times.

You can simply use it in normal function and specify StrictMode.enableDefaults(); at the beginning of onCreate() . Then the app will not crash because of any exception.

0

You have to create a new instance(object) of the AsyncTask class whenever you want to call execute(). e.g. (new MyAsyncTask()).execute();

Rivu Chakraborty
  • 1,372
  • 2
  • 12
  • 37
0

cancel previous task if running and start new task by doing

if (myAsyncTask!= null && myAsyncTask.getStatus() == MyAsyncTask.Status.RUNNING) { 
      myAsyncTask.cancel(true);
}
myAsyncTask.execute();
SachinS
  • 2,223
  • 1
  • 15
  • 25