gpt4 book ai didi

android - Android-Code After Looper

转载 作者:行者123 更新时间:2023-12-03 13:12:57 27 4
gpt4 key购买 nike

我有一个子线程正在运行以无限地执行任务。我想(1)不断将数据发送回UI线程,并且(2)偶尔将数据(对应于按钮)发送到子线程以暂停/继续无限任务。我的问题是子线程卡在了循环程序中,这意味着任务无法执行。

我的问题是:如何在不阻止无限任务的情况下使子线程从UI线程接收消息?

这是我到目前为止的内容:
对于任务(1),我的UI线程中有一个处理程序,它可以工作,而子线程中的无限循环可以发回一条消息,而该消息可以单独工作。

在用户界面线程中:

mMainHandler = new Handler() {
public void handleMessage(Message msg) {
Bundle b;
b = msg.getData();
if (msg.what==1)
Log.i("main", "from child (running) - " + b.getBoolean("running"));
else if (msg.what == 2)
Log.i("main", "from child (count) - " + b.getInt("count"));
}
};

在子线程中(当前使用虚拟任务,直到我制定出框架):
while (true) {
if (running) {
try {
curCount += up;
if (curCount == maxCount)
up = -1;
else if (curCount == minCount)
up = 1;
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("", "local Thread error", e);
}

Bundle b = new Bundle(1);
b.putInt("count", curCount);
Message toMain = mMainHandler.obtainMessage();
toMain.what = 2;
toMain.setData(b);
mMainHandler.sendMessage(toMain);
}
}

对于任务(2),我在UI线程中有一个方法,该方法对应于按下按钮,该按钮将消息发送到工作的子线程,并在子线程中单独运行一个处理程序。

在用户界面线程中:
private void sendRunning(boolean running) {
if (mChildHandler != null) {
Bundle b = new Bundle(1);
b.putBoolean("running", running);

Message msg = mChildHandler.obtainMessage();
msg.what = 1;
msg.setData(b);
mChildHandler.sendMessage(msg);
}
}

在子线程中:
Looper.prepare();
mChildHandler = new Handler() {
public void handleMessage(Message msg) {
Bundle b;
if (msg.what==1){
b = msg.getData();
running = b.getBoolean("running");
Log.i(INNER_TAG, "from main (running) - " + b.getBoolean("running"));
Log.i(INNER_TAG, "running - " + running);
try {
Message toMain = mMainHandler.obtainMessage();
toMain.what = 1;
toMain.setData(b);
mMainHandler.sendMessage(toMain);
} finally {}
}
}
};
Looper.loop();

这些方案中的每一种都可以单独工作,但是要同时做这两个问题就成了问题。如果我将无限任务放在Looper.loop()之后,它将永远无法实现。如果我将其放在Looper.prepare()之前,它将运行一次。如果我将它与弯针一起使用,它仍然只能运行一次。

任何想法将不胜感激:)

这是我的完整代码(减去包装/进口)供引用:
public class MainActivity extends Activity {

Thread thread;
private Handler mMainHandler, mChildHandler;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mMainHandler = new Handler() {
public void handleMessage(Message msg) {
Bundle b;
b = msg.getData();
if (msg.what==1)
Log.i("main", "from child (running) - " + b.getBoolean("running"));
else if (msg.what == 2)
Log.i("main", "from child (count) - " + b.getInt("count"));
}
};

thread = new ChildThread();
thread.start();

// Get a reference to the button
Button buttonStart = (Button)findViewById(R.id.btnStart);
Button buttonStop = (Button)findViewById(R.id.btnStop);

// Set the click listener to run my code
buttonStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,
"Starting...", Toast.LENGTH_SHORT).show();
sendRunning(true);
}
});
buttonStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,
"Stopping...", Toast.LENGTH_SHORT).show();
sendRunning(false);
}
});
}

private void sendRunning(boolean running) {
if (mChildHandler != null) {
Bundle b = new Bundle(1);
b.putBoolean("running", running);

Message msg = mChildHandler.obtainMessage();
msg.what = 1;
msg.setData(b);
mChildHandler.sendMessage(msg);
}
}

@Override
protected void onDestroy() {

Log.i("tag", "stop looping the child thread's message queue");
mChildHandler.getLooper().quit();

super.onDestroy();

}

class ChildThread extends Thread {

private static final String INNER_TAG = "ChildThread";
private boolean running = true;
final int maxCount = 10;
final int minCount = 0;
public int curCount = minCount;
private int up = 1;

public void run() {

while (true) {
if (running) {
try {
curCount += up;
if (curCount == maxCount)
up = -1;
else if (curCount == minCount)
up = 1;
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("", "local Thread error", e);
}

Bundle b = new Bundle(1);
b.putInt("count", curCount);
Message toMain = mMainHandler.obtainMessage();
toMain.what = 2;
toMain.setData(b);
mMainHandler.sendMessage(toMain);
}

this.setName("child");
Looper.prepare();
mChildHandler = new Handler() {
public void handleMessage(Message msg) {
Bundle b;
if (msg.what==1){
b = msg.getData();
running = b.getBoolean("running");
Log.i(INNER_TAG, "from main (running) - " + b.getBoolean("running"));
Log.i(INNER_TAG, "running - " + running);
try {
Message toMain = mMainHandler.obtainMessage();
toMain.what = 1;
toMain.setData(b);
mMainHandler.sendMessage(toMain);
} finally {}
}
}
};

Log.i(INNER_TAG, "Child handler is bound to - " +
mChildHandler.getLooper().getThread().getName());
Looper.loop();
}


}
}

}

最佳答案

只需使用Intent服务而不是此线程即可,因此您可以管理更新的所有UI,以及想要使用一个广播接收器正在使用的Intent服务中的UI进行的操作,并且非常容易处理线程并感染UI,这是很容易的。在后台进程运行时锁定。

关于android - Android-Code After Looper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19395863/

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