java - 访问线程以从另一个方法通知它(Android 应用程序)

标签 java android static multithreading visibility

我正在开发一个 android 应用程序并尝试在不了解线程的情况下处理线程......(是的,我有点愚蠢,我知道) 我会尝试正确且快速地解释它。

在我的 Activity 的 onCreate 方法中,我调用了一个 AlertDialog 让用户选择是从互联网加载数据还是使用以前存储在数据库中的数据直接访问应用程序。
为此,在 onCreate 中,我调用我的方法来引发 AlertDialog,肯定按钮应该启动工作线程进行下载,而否定按钮应该调用 intent 以移动到下一个 Activity 。到目前为止,我得到了这个:

  • 通过不在任何地方调用 wait(),我的 AlertDialog 出现但线程仍然启动
  • 通过在我的线程的第一行调用 wait(),我必须声明它是静态的,以便从我的 AlertDialog 的监听器访问它并且能够 notify() 它或 interrupt(),我收到错误:object not locked by thread before wait()

worker = new Thread(new Runnable() {
        public void run() {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

[我的运行方法的其余部分]

private void miseAJourDesDonnes() {
    confirmInscrip = new AlertDialog.Builder(this).setMessage(
            "Voulez-vous mettre à jour l'intégralité des données de l'application? (Connexion internet requise").setPositiveButton("Mettre à jour",
            okListener).setNegativeButton("Continuer sans", nonListener);
    confirmInscrip.create();
    confirmInscrip.show();
}

OnClickListener okListener = new OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
        Toast.makeText(AccueilSplash.this, "Mise à jour en cours", Toast.LENGTH_SHORT).show();
        worker.notify();
        return;
    }
};
OnClickListener nonListener = new OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
        Toast.makeText(AccueilSplash.this, "Accès direct à l'application", Toast.LENGTH_SHORT).show();
        worker.interrupt();
        Intent entre = new Intent(AccueilSplash.this, Androt.class);
        startActivity(entre);
    }
};

worker 是我的 Thread 实例(bbackground 实例) 我只是愚蠢还是我没有掌握微妙之处? 感谢您的任何回答...

最佳答案

下面是对 wait() 和 notify() 工作原理的快速解释,但我是否建议您不要创建工作线程,除非用户单击确定?如果他们想要停止下载,您可能仍想稍后取消该线程,但在您甚至不知道它是否将被使用之前创建线程似乎不是最佳方法。

为了在对象上调用 wait()notify()、notifyAll(),您必须首先拥有对象的监视器您希望对其调用方法的对象,因此在您的情况下,在可运行的情况下,这将是您需要执行的操作:

Runnable runnable = new Runnable() {
    public void run() {
      // wait(); This call wouldn't work
      syncronized (this) {
        wait();  // This call will work
      }
    }
};

要通知可运行,您还必须拥有监视器

// runnable.notifyAll(); this call will not work
syncronized (runnable) {
    runnable.notifyAll(); // this call will work
}

有关 Java 中线程和并发的更多信息,我建议 Java Concurrency in Practice


Android 中可能有一些我不知道的内置后台任务框架,但使用纯 Java 最简单的方法似乎是这样的:

私有(private)线程downloadThread;

OnClickListener okListener = new OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
        Runnable download = new Runnable() {
            public void run() {
                // Create your input streams and such
                boolean downloadComplete = false;
                while(!downloadComplete  && !Thread.currentThread().isInterruped()) {
                    // Do some downloading
                }
                if (!Thread.currentThread().isInterruped()) {
                    // Alert user of success.
                }
            }
        };
        downloadThread = new Thread(download);
        downloadThread.start();
    }
};
OnClickListener cancelListener = new OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
        downloadThread.interrupt();
    }
};

关于java - 访问线程以从另一个方法通知它(Android 应用程序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2392297/

相关文章:

c++ - 为什么将全局变量和静态变量初始化为其默认值?

android - 使用谷歌登录 `gms.auth.UserRecoverableAuthException: BadAuthentication` 异常 android

android - 如何使用 proguard enable 创建 apk

Android Phonegap 错误 : google is not defined

java - 一个对象拥有所有类成员(静态成员除外)的副本,那么对象是否也拥有内部类的副本?

java - println 的非静态替换

java - Spring数据: Define <mongo:options> using java based config

java - 以递归方式将列表的元素与以下元素进行比较

java - 将 3 字节数组转换为数字

Mac 上 SQLite 的 java.lang.UnsatisfiedLinkError