gpt4 book ai didi

Java/Android 在运行新方法之前等待线程完成

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:31:21 25 4
gpt4 key购买 nike

我有一个 android 应用程序(用 java 编写),它有两个按钮(连接请求数据)。

单击每个按钮时,都会执行一个任务,并且会出现一个进度对话框,以显示任务完成了多少。

为了显示进度对话框,当每个按钮被点击时,任务在一个线程上运行。

connect 按钮只有一项任务 - 在线程上运行。但是,request data 按钮执行两个任务 - 线程上的第一个任务类似于连接按钮,还有第二个任务,refreshInfo(),它必须在线程上的第一个任务 progThread 已完成。

private Button connectButton;
private Button requestDataButton;

private ProgressDialog connectionDialog;
private ProgressDialog requestDataDialog;

private ProgressThread progThread;

private int currentDialog;

public void connectClick(View view) //When the connect button is clicked
{
performAction(1); //Run the thread to perform the action
}

public void requestDownloadClick(View view) //When the request data button is clicked
{
performAction(2); //Run the thread to perform the action

refreshInfo(); //Do something else
}

private void performAction(int type)
{
currentDialog = type;

showDialog(type);

try
{
progThread.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}

这里的关键方法是performAction(int type)。我基本上不希望此方法在 progThread 完成运行之前完成。

如您所见,我已尝试使用 progThread.join() 来阻止该方法在 progThread 完成运行之前继续执行,但是作为 progThread 涉及显示进度对话框,运行progThread.join() 似乎会阻止显示进度对话框,就像当前您单击按钮,第一个任务正在执行,但对话框只在最后闪烁。

谁能想出一种方法来运行线程,正常显示进度对话框,然后运行第二种方法(如果有的话)。

我在下面包含了线程代码,以备不时之需。

private class ProgressThread extends Thread 
{
final static int DONE = 0;
final static int RUNNING = 1; // Class constants defining state of the thread

private Handler progressHandler;
int mState;
int total;

ProgressThread(Handler _handler) // Constructor with an argument that specifies Handler on main thread to which messages will be sent by this thread.
{
progressHandler = _handler;
}

public void run() // Invoked automatically when the Thread starts.
{
mState = RUNNING;

updateProgressBar();

connectButton = (Button) findViewById(R.id.btnConnect);
requestDataButton = (Button) findViewById(R.id.btnRequestDownload);

while (mState == RUNNING)
{
if (currentDialog == 1)
{
try
{
doSomething();

if (something)
{
setState(DONE);

total = 100;

updateProgressBar();

removeDialog(1);

connectButton.setEnabled(false);
}
else
{
total = total + 20;

if (something has reached a limit)
{
setState(DONE);

total = 0;

updateProgressBar();

removeDialog(1);
}
}

updateProgressBar();
}
catch (Exception e)
{

}
}

if (currentDialog == 2)
{
try
{
doSomething();

total = 10;

updateProgressBar();

doSomething();

total = 70;

updateProgressBar();

if (something) //If the download info has not been got
{
setState(DONE);

total = 0;

updateProgressBar();

removeDialog(2);

runOnUiThread(new Runnable()
{
public void run()
{
connectButton.setEnabled(true);

requestDataButton.setEnabled(true);
}
});
}
else
{
total = 100;

updateProgressBar();

setState(DONE);

removeDialog(2);

runOnUiThread(new Runnable()
{
public void run()
{
requestDataButton.setEnabled(false);
}
});
}
}
catch (Exception e)
{
removeDialog(2);

setState(DONE);

runOnUiThread(new Runnable()
{
public void run()
{
connectButton.setEnabled(true);

requestDataButton.setEnabled(true);
}
});
}
}
}
}

// Set current state of thread (use state=ProgressThread.DONE to stop thread)
public void setState(int state)
{
mState = state;
}

public void updateProgressBar()
{
Message msg = progressHandler.obtainMessage(); // Send message (with current value of total as data) to Handler on UI thread so that it can update the progress bar

Bundle b = new Bundle();

b.putInt("total", total);

msg.setData(b);

progressHandler.sendMessage(msg);
}
}

final Handler handler = new Handler() // Handler on the main (UI) thread that will receive messages from the second thread and update the progress.
{
public void handleMessage(Message msg)
{
int total = msg.getData().getInt("total"); // Get the current value of the variable total from the message data and update the progress bar

switch (currentDialog)
{
case 1 :
connectionDialog.setProgress(total);
break;

case 2 :
requestDataDialog.setProgress(total);
break;
}
}
};

protected Dialog onCreateDialog(int id)
{
switch (currentDialog)
{
case 1 :
connectionDialog = new ProgressDialog(this);

connectionDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

connectionDialog.setMax(100);

connectionDialog.setProgress(0);

connectionDialog.setMessage("Connecting To The Device");

progThread = new ProgressThread(handler);

progThread.start();

return connectionDialog;

case 2 :
requestDataDialog = new ProgressDialog(this);

requestDataDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

requestDataDialog.setMax(100);

requestDataDialog.setProgress(0);

requestDataDialog.setMessage("Requesting Download Data");

progThread = new ProgressThread(handler);

progThread.start();

return requestDataDialog;

default :
return null;
}
}

最佳答案

Android API 提供了一个 AsyncTask class其中有两个方法 doInBackgroundonPostExecute。你必须重写它们,在 doInBackground 中做任何你必须做的事情,当工作完成时 onPostExecute 回调将运行。还有一个 onProgressUpdate 回调,这正是您所需要的。

关于Java/Android 在运行新方法之前等待线程完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11774294/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com