首先,我对Android很陌生,所以请光临我:)
背景: 我正在尝试将Java(非GUI)程序转换为在Android上运行。为简单起见,我们假设此程序包含以下文件:
DSGen.java,SInfer.java,Main.java
在Main()方法中,每个类DSGen和SInfer的对象都被初始化并传递给新的Threads并启动。此外,每个类DSGen和SInfer都使用public void run()方法实现Runnable,并且两个run方法都将文本输出到system.out.println()。
线程1.生成100个随机数据值 线程2.对生成数据的100个值进行计算(输出100个结果)
在该程序的Android版本中,我知道UI线程处理所有UI更新。 所以在我的MainActivity.java文件中,我试图声明一个Handler来接收来自"线程2的消息和输出数据"可用于更新MainActivity UI线程中的TextView。当我按下Android UI上的开始按钮时,应用程序开始执行。
问题: 当我运行此应用程序时,我的TextView不会更新,直到处理结束。我还注意到并非所有输出都更新到我的TextView,只有40/100的计算实际上是用于TextView。
程序的实际代码很长,我认为最好只包含与SInfer类的线程,处理程序和run方法相关的部分。
我希望有人可以给我一个伪代码示例或解决方案来处理多个线程,其中runnable方法在2个不同的类文件中声明(不是MainActivity中的内部类),并且可以通过传递消息来更新UI从其中一个线程回到UI线程。
提前谢谢!
public class MainActivity extends Activity {
/* UI Elements */
private TextView output;
/* Thread Handler */
private Handler uiHandler;
/* Handle message override */
public class UIHandler extends Handler {
@Override
public void handleMessage(Message msg) {
output.append(msg.obj.toString());
super.handleMessage(msg);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_run_fsi);
output = (TextView) findViewById(R.id.displayTextView);
uiHandler = new UIHandler();
setStartButtonClickListener();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_run_fsi, menu);
return true;
}
private void setStartButtonClickListener() {
Button startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runFSI();
}
});
}
private void runFSI() {
// initialize SInfer and pass uiHandler
SInfer inferer = SInfer.getInstance(/*other variables*/, uiHandler);
// initialize DSGen
DSGenerator dsGen;
Thread t1 = new Thread(dsGen);
Thread t2 = new Thread(inferer);
t1.start();
t1.yield();
t2.start();
t2.yield();
try {
Thread.sleep(10000);
} catch (Exception e) {
}
inferer.stop();
dsGen.stop();
}
}
SInfer中定义的run方法如下(system.out代码从原始Java代码中遗留下来)
@Override
public void run() {
// System.out.println("Inference: Thread started...");
while (stopFlag == false) {
try {
// System.out.println("SInference: run.........");
Thread.sleep(200);
inferenceResult = doInference();
/* Send result to UI thread */
Message msg = Message.obtain(uiHandler);
msg.obj = inferenceResult.toString();
uiHandler.sendMessage(msg);
} catch (InterruptedException e) {
// System.out.println(e.getMessage());
}
}
}
答案 0 :(得分:0)
您正在运行Thread.sleep(10000);在主线程中(在UI线程中调用OnClick),因此在此10秒内无法在UI中更新任何内容。 尝试在单独的线程中调用runFSI方法。
答案 1 :(得分:0)
覆盖doInBackground()来处理所有后台计算
重写onProgressUpdate(),以便在线程使用publishProgress()方法运行时与UI线程对话。
并覆盖onPostExecute()以在UI线程上执行任何最终操作。