【问题标题】:Boolean value does NOT change on clicking cancel button - How to stop AsyncTask - Android?单击取消按钮时布尔值不会改变 - 如何停止 AsyncTask - Android?
【发布时间】:2014-11-27 21:41:35
【问题描述】:

我是初学者,所以请清楚地解释你的答案。谢谢

编辑 2 我现在有

public class MainActivity extends Activity {

        //other declarations
        public ReadTask readTask;
    protected void onCreate(Bundle savedInstanceState){
     readTask = new ReadTask();

    private OnClickListener test = new OnClickListener()
        {
            @Override
            public void onClick (View V)
            {
                readTask.execute();
                //new ReadTask().execute();

            }

    };
    private OnClickListener cancel = new OnClickListener()
    {
        @Override
        public void onClick (View V)
        {   
            readTask.cancel(true);
            results1.setText("");
        }

检查 EDIT 1 以了解上述代码 (Edit 2) 引发的错误; 谢谢

我在应用中有一个取消按钮。点击这个,就是这个 发生;

    public void onClick (View V)
        {
                    InputMethodManager inputManager = (InputMethodManager)
                    getSystemService(Context.INPUT_METHOD_SERVICE); 
            inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
                       InputMethodManager.HIDE_NOT_ALWAYS);

            new ReadTask().onCancelled();
            new ReadTask().cancel(true);
            results1.setText("Cancelled");
        }

ReadTask 像这样扩展 AsyncTask;

public class ReadTask extends AsyncTask<Void, String, Void>
    {
    BufferedReader reader = null;
    public volatile boolean isCancelled=false;
    //other declarations
    protected void onCancelled() {
        super.onCancelled();
        isCancelled = true;
        new ReadTask().cancel(true);
    }

 @Override
    protected Void doInBackground(Void... params) 
    {
            // isCancelled=false;


        try {
            for(int k=x1[3];k<=x2[3];k++)
            {
                //bunch of code
            Log.w("5.newString", newString);
            String isC1 = String.valueOf(isCancelled);
            Log.w("5.Is cancelled?", isC1); // at this point, VALUE IS ALWAYS FALSE !

            if (isCancelled() || isCancelled == true) {Log.d("Entered","WHY");break;}

                //bunch of code

           } //bunch of catches

这里尝试了两种方法,一种是布尔变量 isCancelled,另一种是 ReadTask().cancel(true); - 两者都不起作用。为什么?

我是新人,所以请把你的答案解释清楚。谢谢

************** EDIT 1 - Logcat 输出********

11-27 17:18:56.626: W/dalvikvm(28775): threadid=1: thread exiting with uncaught exception (group=0x41bcee48)
11-27 17:18:56.636: E/AndroidRuntime(28775): FATAL EXCEPTION: main
11-27 17:18:56.636: E/AndroidRuntime(28775): Process: com.example.pingtest, PID: 28775
11-27 17:18:56.636: E/AndroidRuntime(28775): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.pingtest/com.example.pingtest.MainActivity}: java.lang.NullPointerException
11-27 17:18:56.636: E/AndroidRuntime(28775):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2202)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2252)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at android.app.ActivityThread.access$800(ActivityThread.java:139)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at android.os.Handler.dispatchMessage(Handler.java:102)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at android.os.Looper.loop(Looper.java:136)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at android.app.ActivityThread.main(ActivityThread.java:5103)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at java.lang.reflect.Method.invokeNative(Native Method)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at java.lang.reflect.Method.invoke(Method.java:515)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at dalvik.system.NativeStart.main(Native Method)
11-27 17:18:56.636: E/AndroidRuntime(28775): Caused by: java.lang.NullPointerException
11-27 17:18:56.636: E/AndroidRuntime(28775):    at com.example.pingtest.MainActivity$ReadTask.<init>(MainActivity.java:120)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at com.example.pingtest.MainActivity.onCreate(MainActivity.java:39)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at android.app.Activity.performCreate(Activity.java:5275)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
11-27 17:18:56.636: E/AndroidRuntime(28775):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2166)
11-27 17:18:56.636: E/AndroidRuntime(28775):    ... 11 more
11-27 17:19:05.665: I/Process(28775): Sending signal. PID: 28775 SIG: 9

【问题讨论】:

  • 你想要发生什么?
  • 另外,您是否先测试了按钮?以确保您的取消呼叫甚至被执行?
  • 我希望布尔值 (isCancelled) 在单击按钮后更改为 True。请同时阅读代码中的 cmets。谢谢。
  • 是的,按钮有效,但值保持不变。我想在单击取消按钮后停止正在运行的 AsynTask。

标签: android android-asynctask boolean


【解决方案1】:

您好,我对您的代码进行了一些更改,请查看说明。

 public class Asyn extends Activity {

    public ReadTask readTask;
    // keep global to prevent creating new async task on every time button click
    boolean isCancelled = true;
    TextView results1;
    Button start, end;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.qww);
        start = (Button) findViewById(R.id.button1);
        end = (Button) findViewById(R.id.button2);
        start.setOnClickListener(test);
        end.setOnClickListener(cancel);
        results1 = (TextView) findViewById(R.id.textView1);
    }

    private OnClickListener test = new OnClickListener() {
        @Override
        public void onClick(View V) {
            if (isCancelled) { // checked to prevent creating new async task on
                                // every time button click
                Toast.makeText(Asyn.this, "new task started", Toast.LENGTH_LONG)
                        .show();
                readTask = new ReadTask();
                readTask.execute();
                isCancelled = false;
            } else {
                Toast.makeText(Asyn.this, "Task already runing",
                        Toast.LENGTH_LONG).show();
            }

        }

    };
    private OnClickListener cancel = new OnClickListener() {
        @Override
        public void onClick(View V) {
            if (null != readTask) {
                Toast.makeText(Asyn.this, "Task stop", Toast.LENGTH_LONG)
                        .show();
                readTask.cancel(true);
                isCancelled = true;
            }
            results1.setText("");
        }
    };

        private class ReadTask extends AsyncTask<Void, String, Void> {


    protected void onProgressUpdate(String... values) {
         super.onProgressUpdate(values);
        results1.setText(values[0].toString());


    }
    @Override
    protected Void doInBackground(Void... params) {

        try {
            for (int k = 0; k <= 10; k++) {
                // bunch of code
                Log.w("5.newString", k + "");
                String isC1 = String.valueOf(isCancelled);
                Log.w("5.Is cancelled?", isC1); // at this point, VALUE IS


                    //below line for instant update as soon as the value is changed
                 publishProgress("  "+k + "");

                // use thread to see the update otherwise remove it
                    Thread.sleep(2000); 
                if (isCancelled() || isCancelled == true) {
                    Log.d("Entered", "WHY");
                    break;
                }

                // bunch of code

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        // assign true to isCancelled so that user can start task again
        isCancelled = true;
    }
}
}

【讨论】:

  • 嗨,每次我输入“public ReadTask readTask;”在 MainActivty 上,应用程序甚至没有启动。致命例外:主要。如果我将其注释掉并在每个(测试和取消按钮)上实例化一个新的 readTask,应用程序。运行。这个类看起来像这样——公共类“ReadTask extends AsyncTask”。请告诉我为什么会这样。谢谢。
  • 请将 ReadTask 类设为私有,因为它是内部类,我已经对其进行了编辑。您能解释一下您是要在每次按钮单击时创建新任务还是相同的异步任务。目前它只创建一个实例。
  • 我只需要 1 个异步任务,我希望在点击取消按钮时取消此异步任务。目前,取消有效,但是,它仅在完成 ​​doInBackground() 任务中的当前循环后才取消任务。如何解决这个问题?谢谢。
  • 你是钱德拉的救星! - 我在 onCreate() 方法中初始化 readTask 失败。现在,完美运行。在循环内停止。我不敢相信我评论了那条线。再次感谢您的帮助。现在唯一的问题是,传递给 onProgressUpdate() 方法的 STR 只会在循环结束后打印到我的 UI 一次......我希望它在每次进入时打印。
  • PL.检查这些问题 - 他们有更多详细信息:stackoverflow.com/questions/27198413/… AND stackoverflow.com/questions/27197837/…
【解决方案2】:

它不起作用,因为每次您都从 ReadTask 创建新对象。如果你想取消现有的工作。你应该这样做:

  public class MainActivity extends Activity { 
   ReadTask readTask; 

   @Override
   public void onCreate (Bundle b) {
       ...
       readTask = new ReadTask();

       btnStart.setOnClickListener(new OnClickListener() {
          @Override 
          void onClick(View v) {
            readTask.execute();
          }
       }

       btnCancel.setOnClickListener(new OnClickListener() {
          @Override 
          void onClick(View v) {
            readTask.cancel();
          }
       }
   }

 }

【讨论】:

  • 是的,我同意,我第一次错过了。
  • 不,ReadTask.execute() 是通过单击应用程序上的不同按钮启动的。我不想通过单击取消按钮来启动另一个线程。我想停止现有的。你明白吗?
  • 这就是我要说的。您应该在您的类和取消按钮的 onClick 方法中定义您的对象,为该对象调用取消并且不要创建新对象。我说清楚了吗?
  • 如果我执行 ReadTask readTask = new ReadTask();在 MainActivity 下,应用程序无法启动,我在 Logcat 中收到“FATAL exception:main”错误。
  • 我像你的例子一样尝试过,readTask = new ReadTask();在 bundle 和 ReadTask 里面 readTask;在 MainActivity 中。 readTask.execute();在第一个按钮和 readTask.cancel(true);取消按钮内。但是 FATAL EXCEPTION:main 发生并且应用程序甚至没有启动。为什么?
【解决方案3】:
new ReadTask().onCancelled();
new ReadTask().cancel(true);

这部分代码是错误的,因为它们都引用了 ReadTask 类的不同实例。 你可以声明一个 ReadTask 类的全局变量

public ReadTask rt;

并在您的 onCreate() 方法上对其进行初始化。

rt = new ReadTask();

那么您已经可以在活动的每个部分使用它了 使用rt.execute() 启动它并使用rt.cancel(true) 停止它

【讨论】:

  • 嗨,我做到了,如果我这样做,我会得到一个 NULL 指针异常和应用程序。没有启动。
  • 我像你的例子一样尝试过,readTask = new ReadTask();在 bundle 和 ReadTask 里面 readTask;在 MainActivity 中。 readTask.execute();在第一个按钮和 readTask.cancel(true);取消按钮内。但是 FATAL EXCEPTION:main (Null 指针异常) 发生并且应用程序甚至没有启动。为什么?
  • 嗨,我不能分享整个代码,大部分都在问题中。变化是,我有一个“ReadTask readTask;”在 MainActivity 中。一个“readTask = new ReadTask();”包内。 “readTask.execute();”在第一个按钮和“readTask.cancel(true);”内取消按钮内。此外,问题中的 Edit 显示了 LogCat 输出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-10
  • 2021-02-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多