我是Android新手,我正在尝试使用UI-Thread,所以我写了一个简单的测试活动。但我认为我误解了一些东西,因为单击按钮 - 应用程序不再响应
public class TestActivity extends Activity {
Button btn;
int i = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runThread();
}
});
}
private void runThread(){
runOnUiThread (new Thread(new Runnable() {
public void run() {
while(i++ < 1000){
btn.setText("#"+i);
try {
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}));
}
}
答案 0 :(得分:191)
以下是runThread
功能的修正片段。
private void runThread() {
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
答案 1 :(得分:77)
将其包装为函数,然后从后台线程中调用此函数。
public void debugMsg(String msg) {
final String str = msg;
runOnUiThread(new Runnable() {
@Override
public void run() {
mInfo.setText(str);
}
});
}
答案 2 :(得分:26)
你有它从前到后。您点击按钮会调用runOnUiThread()
,但这不是必需的,因为点击处理程序已在UI线程上运行。然后,runOnUiThread()
中的代码将启动一个新的后台线程,您尝试执行UI操作,然后失败。
相反,只需直接从点击处理程序启动后台线程。然后,将呼叫包含在btn.setText()
的呼叫中runOnUiThread()
。
答案 3 :(得分:10)
runOnUiThread(new Runnable() {
public void run() {
//Do something on UiThread
}
});
答案 4 :(得分:8)
有几种使用runOnUiThread()的技术,让我们看看所有
这是我的主线程(UI线程),名为 AndroidBasicThreadActivity ,我将以各种方式从工作线程更新它 -
public class AndroidBasicThreadActivity extends AppCompatActivity
{
public static TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_basic_thread);
textView = (TextView) findViewById(R.id.textview);
MyAndroidThread myTask = new MyAndroidThread(AndroidBasicThreadActivity.this);
Thread t1 = new Thread(myTask, "Bajrang");
t1.start();
}
}
1.)通过将Activity的实例作为工作线程的参数传递
class MyAndroidThread implements Runnable
{
Activity activity;
public MyAndroidThread(Activity activity)
{
this.activity = activity;
}
@Override
public void run()
{
//perform heavy task here and finally update the UI with result this way -
activity.runOnUiThread(new Runnable()
{
@Override
public void run()
{
AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
}
});
}
}
2.。在工作线程中使用View的post(Runnable runnable)方法
class MyAndroidThread implements Runnable
{
Activity activity;
public MyAndroidThread(Activity activity)
{
this.activity = activity;
}
@Override
public void run()
{
//perform heavy task here and finally update the UI with result this way -
AndroidBasicThreadActivity.textView.post(new Runnable()
{
@Override
public void run()
{
AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
}
});
}
}
3.。通过使用android.os包中的Handler类 如果我们没有上下文(this / getApplicationContext())或Activity的实例(AndroidBasicThreadActivity.this),那么我们必须使用如下的Handler类 -
class MyAndroidThread implements Runnable
{
Activity activity;
public MyAndroidThread(Activity activity)
{
this.activity = activity;
}
@Override
public void run()
{
//perform heavy task here and finally update the UI with result this way -
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
}
});
}
}
答案 5 :(得分:2)
如果在片段中使用,则只需编写
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
//Do something on UiThread
}
});
答案 6 :(得分:1)
你的这个:
@UiThread
public void logMsg(final String msg) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Log.d("UI thread", "I am the UI thread");
}
});
}
答案 7 :(得分:1)
我们使用Worker Thread使应用程序更流畅并避免ANR。在工作程序Tread中进行了繁重的工作后,我们可能需要更新UI。 用户界面只能通过用户界面线程进行更新。在这种情况下,我们使用Handler或runOnUiThread都具有在UI Thread中执行的Runnable运行方法。 onClick方法在UI线程中运行,因此无需在此处使用runOnUiThread。
使用Kotlin
在活动中
this.runOnUiThread {
// Do stuff
}
来自片段
activity?.runOnUiThread {
// Do stuff
}
使用Java ,
this.runOnUiThread(new Runnable() {
void run() {
// Do stuff
}
});
答案 8 :(得分:0)
您可以使用此示例:
在下面的示例中,我们将使用此工具从a发布结果 由后台线程处理的同义词搜索。
要在OnCreate活动回调期间完成目标,我们将进行设置 onClickListener在创建的线程上运行searchTask。
当用户点击“搜索”按钮时,我们将创建一个Runnable匿名 搜索在R.id.wordEt EditText中键入的单词并启动的类 线程执行Runnable。
搜索完成后,我们将创建一个Runnable SetSynonymResult实例 通过UI线程将结果发布回同义词TextView。
这种技术有时并不是最方便的技术,特别是当我们不这样做时 可以访问Activity实例;因此,在接下来的章节中,我们是 将讨论更简单和更清洁的技术,以从后台更新UI 计算任务。
public class MainActivity extends AppCompatActivity {
class SetSynonymResult implements Runnable {
String synonym;
SetSynonymResult(String synonym) {
this.synonym = synonym;
}
public void run() {
Log.d("AsyncAndroid", String.format("Sending synonym result %s on %d",
synonym, Thread.currentThread().getId()) + " !");
TextView tv = (TextView) findViewById(R.id.synonymTv);
tv.setText(this.synonym);
}
}
;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button search = (Button) findViewById(R.id.searchBut);
final EditText word = (EditText) findViewById(R.id.wordEt);
search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Runnable searchTask = new Runnable() {
@Override
public void run() {
String result = searchSynomim(word.getText().toString());
Log.d("AsyncAndroid", String.format("Searching for synonym for %s on %s",
word.getText(), Thread.currentThread().getName()));
runOnUiThread(new SetSynonymResult(result));
}
};
Thread thread = new Thread(searchTask);
thread.start();
}
});
}
static int i = 0;
String searchSynomim(String word) {
return ++i % 2 == 0 ? "fake" : "mock";
}
}
来源:
答案 9 :(得分:0)
这就是我使用它的方式:
runOnUiThread(new Runnable() {
@Override
public void run() {
//Do something on UiThread
}
});
答案 10 :(得分:0)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gifImageView = (GifImageView) findViewById(R.id.GifImageView);
gifImageView.setGifImageResource(R.drawable.success1);
new Thread(new Runnable() {
@Override
public void run() {
try {
//dummy delay for 2 second
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//update ui on UI thread
runOnUiThread(new Runnable() {
@Override
public void run() {
gifImageView.setGifImageResource(R.drawable.success);
}
});
}
}).start();
}
答案 11 :(得分:0)
尝试以下操作:getActivity().runOnUiThread(new Runnable...
这是因为:
1)您对 runOnUiThread 的调用中的隐式引用是指 AsyncTask ,而不是您的片段。
2)片段没有runOnUiThread。
但是,活动确实如此。
请注意,如果您已经在主线程上,那么Activity仅执行Runnable,否则将使用Handler。如果您不想担心它的上下文,则可以在片段中实现Handler,这实际上非常简单:
//一个类实例
private Handler mHandler = new Handler(Looper.getMainLooper());
///代码中的其他任何地方
mHandler.post(<your runnable>);
// ^它将始终在主线程的下一个运行循环上运行。