java 访问一个线程以通过另一种方法通知它(Android 应用程序)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2392297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Access a thread to notify it from another method (Android application)
提问by Sephy
I'm developping an android application and trying to deal with threads without really knowing a lot about them... (Yeah bit stupid of me, I know) I'll try to explain it properly and quite quickly.
我正在开发一个 android 应用程序并试图处理线程而不真正了解它们......(是的,我有点愚蠢,我知道)我会尝试正确且很快地解释它。
In the onCreate method of my activity, I'm calling an AlertDialog to make the user choose to either load data from the internet or directly access the application using the data previously stored in database.
For that, in the onCreate, I call my method to raise the AlertDialog, positive button should start the worker thread to download, and negative button should call intent to move to next activity. So far, I got this :
在我的活动的 onCreate 方法中,我调用 AlertDialog 让用户选择是从 Internet 加载数据还是使用先前存储在数据库中的数据直接访问应用程序。
为此,在 onCreate 中,我调用我的方法来引发 AlertDialog,正按钮应启动工作线程进行下载,负按钮应调用意图移动到下一个活动。到目前为止,我得到了这个:
- by not calling
wait()anywhere, my AlertDialog appears but the thread starts anyway - by calling
wait()at the first line of my thread, I have to declare it static to access it from the listeners of my AlertDialog and be able tonotify()it orinterrupt(), I receive the error:object not locked by thread before wait().
- 通过不在
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();
}
[rest of my run method]
[我的运行方法的其余部分]
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 is my instance of Thread (the bbackground one) Am I just being dumb or Is there a subtility I havent grasped? thanks for any answer...
worker 是我的 Thread 实例(bbackground 实例)我只是愚蠢还是有我没有掌握的微妙之处?感谢您的任何回答...
回答by Yanamon
Below is a quick explanation of how wait() and notify() works but might I suggest that you just don't create the worker thread unless the user clicks ok? You may still want to cancel the thread later if they want to stop the download but creating the thread before you even know if it going to be used doesn't seem like the best approach.
下面是对 wait() 和 notify() 如何工作的快速解释,但我是否建议您不要创建工作线程,除非用户点击确定?如果他们想停止下载,您可能仍想稍后取消该线程,但在您知道它是否将被使用之前创建该线程似乎不是最好的方法。
In order to call wait(), notify(),or notifyAll()on an object you must first own the monitor of the object you wish to call the method on, so in you case within the runnable this would be how you would need to do it:
为了调用wait(),notify(),或notifyAll()在一个对象上,您必须首先拥有您希望调用该方法的对象的监视器,所以在您的情况下,在 runnable 中,这将是您需要执行的操作:
Runnable runnable = new Runnable() {
public void run() {
// wait(); This call wouldn't work
syncronized (this) {
wait(); // This call will work
}
}
};
To notify that runnable you would also have to have the monitor
要通知该 runnable,您还必须拥有监视器
// runnable.notifyAll(); this call will not work
syncronized (runnable) {
runnable.notifyAll(); // this call will work
}
For more information about threads and concurrency in Java I would suggest Java Concurrency in Practice
有关 Java 中线程和并发的更多信息,我建议在实践中使用 Java 并发
There may be some built in framework for background tasks in Android that I don't know about but using pure java the easiest approach to this seems like it would be something like this:
Android 中可能有一些我不知道的用于后台任务的内置框架,但是使用纯 Java 最简单的方法似乎是这样的:
private Thread 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();
}
};
回答by Steve Haley
I'm new to using threads as well, but you could try reading this exampleto give you a good starting point. It's about progress dialogs, but it illustrates how to manage threads and start them up at the right time. The really useful code is collapsed under the 'see more about Progress Dialgos with a second Thread' section.
我也是使用线程的新手,但您可以尝试阅读此示例,为您提供一个良好的起点。它是关于进度对话框的,但它说明了如何管理线程并在正确的时间启动它们。真正有用的代码折叠在“使用第二个线程查看有关进度对话框的更多信息”部分下。
Going to your code, I think your mistake is in how you declare your thread. Try instead creating is as a class extending Thread. e.g.
转到您的代码,我认为您的错误在于您如何声明您的线程。尝试创建 is 作为扩展 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
}
}
Then nothing happens with this Thread until you instantiate it with the following, in your onClickListeners.
然后这个线程不会发生任何事情,直到你在你的 onClickListeners 中使用以下内容实例化它。
Worker worker = new Worker(handler)
Even after that it won't actually start until you call worker.start(). Define your handler along the lines of
即使在那之后它也不会真正启动,直到你调用 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);
}
}
};
Hope that helps you get started! Do read the link above, as I imagine you'll want some kind of progress dialog as well when it's actually doing the loading from the website. Or perhaps it would be done in a background service, but I couldn't help you with that.
希望能帮助您入门!请阅读上面的链接,因为我想您在实际从网站加载时也需要某种进度对话框。或者它可能会在后台服务中完成,但我无法帮助您。

