简体   繁体   中英

When I press the button that activates the asynctask in the fragment the app stop working

I open a new fragment in my application, and I want to calculate the price and print it every second that passes (by asyncTask), but when I run the application stop working. can you help me to find the problem?

public class RandomDrive extends Fragment {
private Chronometer chronometer;
private Button start;
private Button stop;
private TextView price;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_random_drive, container, false);
    chronometer = (Chronometer) v.findViewById(R.id.chronometer);
    price = v.findViewById(R.id.see_price);
    class SyncTaskCounter extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            double price = 0;

            while (!isCancelled()) {
                price = price + 0.05;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                printPrice(price);
            }
            return null;
        }
        @Override
        protected void onCancelled() {
            super.onCancelled();
        }
    }
    final SyncTaskCounter asyncTaskCount;
    asyncTaskCount = new SyncTaskCounter();
    start = (Button) v.findViewById(R.id.start);
    start.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            chronometer.setBase(SystemClock.elapsedRealtime());
            chronometer.start();

            asyncTaskCount.execute();
        }
    });
    stop = (Button) v.findViewById(R.id.stop);
    stop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            chronometer.stop();
            asyncTaskCount.cancel(true);

        }
    });
    return v;
}

public void printPrice(double price1) {
    price.setText("the price is: " + price1 + " shekel");

}
}

The problem is in asyncTask, because when I ran the function without asyncTask and calculated the price only at the end - the application run.

On Android you have to run all UI code on UI Thread. Code in AsyncTask in executed in other thread therefor it cannot call UI methods.

To do that you should use Handler (code will be called in UI thread): https://developer.android.com/reference/android/os/Handler

final Handler h=new Handler();
h.postDelayed(new Runnable() {
   public void run() {
      printPrice(price);
      price = price + 0.05;
      h.postDelayed(this, 1000); // call for next update
   }
}, 1000);

I you have to use AsyncTask, then you should update UI from method: onProgressUpdate https://developer.android.com/reference/android/os/AsyncTask

class SyncTaskCounter extends AsyncTask<Void, Double, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            double price = 0;

            while (!isCancelled()) {
                price = price + 0.05;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                publishProgress(price); // this instructs to call onProgressUpdate from UI thread.
            }
            return null;
        }
        @Override
        protected void onProgressUpdate(Double... price) {
                printPrice(price[0]);  // this is called on UI thread
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM