如果在UI线程上运行Runnable不是一个选项,如何延迟生成的线程?

我之前的问题有问题,我不确定我的代码是否有内存泄漏。 一些答案涉及它在UI线程上运行,因此阻塞。 确实,它在UI线程上运行,并不会产生新的线程。

因此,为了解决这个问题,我使用Thread而不是Handler在UI之外生成一个新线程。 现在的问题是我无法像在UI线程中运行的那样延迟它。

这是我之前的问题,我的原始UI线程代码是: 这个Runnable是否可以防止内存泄漏? 以下是产生新线程的更新代码:

 package com.example.helloworld; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.widget.TextView; import android.util.Log; import java.lang.ref.WeakReference; public class HelloWorldActivity extends Activity { private static TextView txtview; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); txtview = (TextView) findViewById(R.id.mainview); Thread t = new Thread(new WeakRunnable(txtview)); t.start(); } private static final class WeakRunnable implements Runnable { private final WeakReference mtextview; protected WeakRunnable(TextView textview){ mtextview = new WeakReference(textview); } @Override public void run() { TextView textview = mtextview.get(); if (textview != null) { try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } int test = 5*5; txtview.setText("Hola Mundo"+test); } Log.d("com.example.helloworld", "" + Thread.currentThread().getName()); // Outputs "Thread-" if not running on UI thread } } } 

它只是设置视图文本并附加5*5的结果。

一旦我启动应用程序它退出自己,我不明白为什么。 有些东西告诉我,我以错误的方式推迟它或使用runOnUiThread错误。 甚至改变txtview.setText("Hola Mundo"+test); to runOnUiThread( txtview.setText("Hola Mundo"+test) ); 没有编译给出错误: 'void' type not allowed here

简而言之:计算(在这种情况下为5*5 )应该在一个单独的线程上完成,以避免阻塞主(UI)线程,并且应该在UI上设置文本,从单独的线程中获取计算项。 你自己的一个简单例子也可以。

更新我已经发布了我自己的问题实现AsyncTask的答案。

您可以使用条件直到满足它而不是使用thread.sleep();

  Condition.wait(new Callable() { @Override public Boolean call() throws Exception { return textview != null; } }); 

使用Handler类和Views中的postDelayed方法

更改,

  Thread t = new Thread(new WeakRunnable(txtview)); t.start(); 

至 :

  txtview.postDelayed(new WeakRunnable(txtview), 1500); 

然后在runnable中删除以下sleep子句,因为它不再需要

  try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } 

正如@Axxiss所说,这种情况更适合AsyncTask 。 我更新了我的代码以使用带有WeakReference AsyncTask来避免内存泄漏:

 package com.example.helloworld; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.AsyncTask; import android.widget.TextView; import android.util.Log; import java.lang.ref.WeakReference; public class HelloWorldActivity extends Activity { private static TextView txtview; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); txtview = (TextView) findViewById(R.id.mainview); SimpleTask objSimpleTask=new SimpleTask(); objSimpleTask.execute(); } private static class SimpleTask extends AsyncTask { private WeakReference mtextview = new WeakReference(txtview); @Override protected String doInBackground(Void... params) { Log.d("com.example.helloworld", "" + Thread.currentThread().getName()); try{ Thread.sleep(1500); } catch(InterruptedException ex) { Thread.currentThread().interrupt(); } return "Hola Mundo"; } @Override protected void onPostExecute(String result) { TextView mtxtview = mtextview.get(); mtxtview.setText(result); } } } 

doInBackground在一个单独的线程中执行代码,而稍后您可以使用onPostExecute捕获结果并在主(UI)线程中执行它而不需要任何装饰。