zoukankan      html  css  js  c++  java
  • 一手遮天 Android

    项目地址 https://github.com/webabcd/AndroidDemo
    作者 webabcd

    一手遮天 Android - 异步和多线程: Future, FutureTask 的关闭和异常处理

    示例如下:

    /async/FutureTaskDemo2.java

    /**
     * Future, FutureTask 的关闭和异常处理(具体的异常捕获和处理的说明详见下面的示例代码)
     *     boolean cancel(boolean mayInterruptIfRunning) - 取消 Future 异步任务,成功地调用 cancel() 则返回 true(如果异步任务的状态是已取消或者已中断,则返回 false)
     *         mayInterruptIfRunning 为 false 的方式:只会设置异步任务的状态为取消状态
     *         mayInterruptIfRunning 为 true 的方式:调用异步任务线程的 interrupt() 方法,同时设置异步任务的状态为取消状态
     *     isCancelled() - 异步任务是否是取消状态,被取消或者被中断则此值为 true
     *     isDone() - 异步任务是否是完成状态,正常完成或者发生异常或者被取消或者被中断则此值为 true
     *
     *
     * 注: 因为 FutureTask 实现了 Runnable 接口,所以可以通过 Thread 来执行
     */
    
    package com.webabcd.androiddemo.async;
    
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    import com.webabcd.androiddemo.R;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.CancellationException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class FutureTaskDemo2 extends AppCompatActivity {
    
        private TextView _textView1;
        private Button _button1;
        private Button _button2;
        private Button _button3;
    
        private FutureTask<String> mTask;
        private Thread mThread;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_async_futuretaskdemo2);
    
            _textView1 = (TextView) findViewById(R.id.textView1);
            _button1 = (Button) findViewById(R.id.button1);
            _button2 = (Button) findViewById(R.id.button2);
            _button3 = (Button) findViewById(R.id.button3);
    
            sample();
        }
    
        private void sample() {
            _button1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 启动一个后台线程,用于演示 Future, FutureTask 的关闭和异常处理
                    mThread = new Thread(new MyRunnable());
                    mThread.setDaemon(true);
                    mThread.start();
                }
            });
    
            _button2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mTask != null) {
                        // 如果异步任务的状态是已取消或者已中断,则不做任何处理,并返回 false;反之则会调用异步任务线程的 interrupt() 方法,同时设置异步任务的状态为取消状态,并返回 true
                        boolean cancelResult = mTask.cancel(true);
                        writeMessage("是否成功地调用了 Future 的 cancel() 方法:" + cancelResult);
                    }
                }
            });
    
            _button3.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mThread != null) {
                        // 在 Future 的 get() 阻塞过程中,如果调用了阻塞所在线程的 interrupt() 方法,则会捕获到 InterruptedException 异常
                        mThread.interrupt();
                        writeMessage("调用 Future 的 get() 阻塞所在线程的 interrupt() 方法");
                    }
                }
            });
        }
        private class MyRunnable implements Runnable {
            @Override
            public void run() {
                mTask = new FutureTask<String>(new Callable<String>() {
                    @Override
                    public String call() throws Exception {
    
                        try {
                            // 如果调用 Future 的 cancel() 时指定了 mayInterruptIfRunning 为 true 则这里会抛出 InterruptedException 异常并设置任务状态,反之则只设置任务状态
                            Thread.sleep(5 * 1000);
                        } catch (InterruptedException e) {
                            writeMessage("异步任务被 Interrupted 了");
                        }
    
                        throw new Exception("执行异步任务时发生异常");
                    }
                });
                Thread thread = new Thread(mTask);
                thread.setDaemon(true);
                thread.start();
    
                try {
                    String result = mTask.get(10 * 1000, TimeUnit.MILLISECONDS);
                    writeMessage("result " + result);
                } catch (InterruptedException e) {
                    writeMessage("当前线程(阻塞所在线程,也就是调用异步任务的线程,而不是异步任务线程本身)被 Interrupted 了");
                } catch (ExecutionException e) {
                    writeMessage("当 Callable 的 call() 抛出 Exception 异常时,则会捕获到 ExecutionException 异常");
                } catch (TimeoutException e) {
                    // 本例默认不会执行到这里,如需要查看效果则将 get() 超时设置小一点即可
                    writeMessage("到了指定的超时时间,仍未收到异步任务的返回结果,则会捕获到 TimeoutException 异常");
                    // 如异步任务不再需要,请在这里取消这个超时的异步任务
                    mTask.cancel(true);
                } catch (CancellationException e) {
                    writeMessage("成功地调用了 Future 的 cancel() 方法后,则会捕获到 CancellationException 异常");
                }
    
                // isCancelled() - 被取消或者被中断则此值为 true
                // isDone() - 正常完成或者发生异常或者被取消或者被中断则此值为 true
                writeMessage(String.format("isDone:%b, isCancelled:%b", mTask.isDone(), mTask.isCancelled()));
            }
        }
    
    
        private void writeMessage(final String message) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    _textView1.append(String.format("%s
    ", message));
                }
            });
        }
    }
    
    

    /layout/activity_async_futuretaskdemo2.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:text="启动一个后台线程,用于演示 Future, FutureTask 的关闭和异常处理" />
    
        <Button
            android:id="@+id/button2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:text="调用 Future 的 cancel() 方法" />
    
        <Button
            android:id="@+id/button3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:text="调用 Future 的 get() 阻塞所在线程的 interrupt() 方法" />
    
    </LinearLayout>
    

    项目地址 https://github.com/webabcd/AndroidDemo
    作者 webabcd

  • 相关阅读:
    pycharm的集成vim
    几款在线脑图制作工具
    编辑器vim简介
    常用服务器ftp、ssh
    56. Merge Intervals
    58. Length of Last Word
    55. Jump Game
    53. Maximum Subarray
    52. N-Queens II
    51. N-Queens
  • 原文地址:https://www.cnblogs.com/webabcd/p/android_async_FutureTaskDemo2.html
Copyright © 2011-2022 走看看