【问题标题】:Using thread annotation not being inspected as expected使用未按预期检查的线程注释
【发布时间】:2017-11-21 16:41:38
【问题描述】:

我想通知开发人员一个方法必须在主线程中,所以我写了以下代码:

  @MainThread
    public void showToast(@NonNull String text) {
        Toast.makeText(this, text, Toast.LENGTH_LONG).show();
    }

比我写的:

   new Thread(new Runnable() {
        @Override
        public void run() {
            showToast("");
        }
    }).start();

并且编译器没有将此标记为错误,这与我使用的 @StringRes 和其他注释不同。

知道为什么吗?

【问题讨论】:

    标签: android android-studio annotations metadata


    【解决方案1】:

    为线程推理提供您自己的注释

    lint 检查(恰当地命名为“WrongThread”)无法推断调用 showToast 方法的线程,除非您提供将方法标记为 @WorkerThread 等之一的注释。

    获取您的原始代码并将@WorkerThread 注解添加到run 方法中:

    new Thread(new Runnable() {
        @Override
        @WorkerThread
        public void run() {
            showToast("");
        }
    }).start();
    

    它会正确生成如下lint检查警告:

    AsyncTask 的特殊情况

    AsyncTask 的方法标有正确的线程注释 (link to source):

    @WorkerThread
    protected abstract Result doInBackground(Params... params);
    

    如果您碰巧使用AsyncTask,您将免费收到警告,如下例所示:

    new AsyncTask<String, String, String>() {
        @Override
        protected String doInBackground(String... strings) {
            showToast(""); //warning here: method showToast must be called from the main thread
                           //currently inferred thread is worker
            return "";
        }
    

    对于其他异步模式,您必须添加自己的 @WorkerThread 或其他注释。

    不同线程的完整列表是here

    @MainThread
    @UiThread
    @WorkerThread
    @BinderThread
    @AnyThread
    

    【讨论】:

    • 我在使用 Thread 注释时根本看不到任何警告。我们是否必须更改 Android Studio 上的某些设置。
    • @UbaierBhat 它应该默认启用,但您可以检查您的 Android Studio 检查设置以进行“错误线程”检查
    猜你喜欢
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多