【问题标题】:Access a thread to notify it from another method (Android application)访问线程以通过其他方法通知它(Android 应用程序)
【发布时间】:2010-03-06 11:23:17
【问题描述】:

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

在我的活动的 onCreate 方法中,我正在调用 AlertDialog 以使用户选择从 Internet 加载数据或使用先前存储在数据库中的数据直接访问应用程序。
为此,在 onCreate 中,我调用我的方法来引发 AlertDialog,肯定按钮应该启动工作线程下载,否定按钮应该调用意图移动到下一个活动。到目前为止,我得到了这个:

  • 通过不在任何地方调用 wait(),我的 AlertDialog 会出现,但线程仍会启动
  • 通过在我的线程的第一行调用wait(),我必须将它声明为静态,以便从我的AlertDialog 的侦听器访问它,并且能够notify() 它或interrupt(),我收到错误:@ 987654325@.

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 之一) 我只是愚蠢还是有我没有掌握的微妙之处? 感谢您的任何回答...

【问题讨论】:

  • 发布更多代码。我想你的 AlertDialog 有问题。
  • 好的,用我的提醒编辑帖子
  • 你在哪里调用worker.start()?

标签: java android static multithreading visibility


【解决方案1】:

下面是对 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 最简单的方法似乎是这样的:

私有线程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();
    }
};

【讨论】:

  • mm,我认为如果你在 oklistener 中创建你的新线程,你不能从 cancellistener 中中断它......一个排除另一个。谢谢解释(晚上再仔细看看,我需要在线程上做一些工作),我终于从android的AsyncTask类中得到了一个解决方法:developer.android.com/intl/fr/reference/android/os/…
  • @Sephy:AsyncTask 是执行后台任务的方式。它提供了相当不错的 api。
【解决方案2】:

我也是使用线程的新手,但您可以尝试阅读此example 来为您提供一个良好的起点。它是关于进度对话框的,但它说明了如何管理线程并在正确的时间启动它们。真正有用的代码在“查看更多关于带有第二个线程的 Progress Dialgos”部分下。

转到您的代码,我认为您的错误在于您声明线程的方式。尝试创建作为扩展 Thread 的类。例如

private class Worker extends Thread{
    Handled mHandler;  //See the example linked above for how to use handlers
    int progress;
    //and whatever other variables it might need

    worker(Handled h){
        mHandler = h;
        //and any other initialisation you need
    }

    public void run(){
        //and all your code here
    }
}

然后,除非您在 onClickListeners 中使用以下内容实例化它,否则此线程不会发生任何事情。

Worker worker = new Worker(handler)

即使在那之后,它也不会真正开始,直到你调用 worker.start()。按照以下方式定义您的处理程序

final Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        int progress = msg.getData().getInt("progress");
        loadingDialog.setProgress(progress);
        if (progress >= 100){
            dismissDialog(LOADING_DIALOG);
        }
    }
};

希望能帮助您入门!请阅读上面的链接,因为我想您在实际从网站加载时也会需要某种进度对话框。或者,它可能会在后台服务中完成,但我无法帮助您。

【讨论】:

  • 我实际上正在尝试 AsyncTask,这正是我所需要的,并且在 Android 中得到了很好的实现,如果我没有找到,我会回到你的建议。谢谢
猜你喜欢
  • 2022-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
相关资源
最近更新 更多