抱歉,我的上一个问题编写得不好。所以我删除了内容并重新构建了我的问题。
我喜欢@ChrisBunney回答我的问题,并在另一个帖子中处理图像。
以下是正确的代码
public class TestActivity extends ListActivity {
int count =0;
List<String> listString = null;
String[] mString = null;
private RefreshHandler mRedrawHandler = new RefreshHandler();
class RefreshHandler extends Handler {
@Override
public void handleMessage(Message msg) {
TestActivity.this.updateUI();
}
public void sleep(long delayMillis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), delayMillis);
}
};
private void updateUI(){
mRedrawHandler.sleep(1000);
listString.add("Test "+count++);
String[] mString = new String[listString.size()];
int i = 0;
for(String string : listString){
mString[i++]= string;
}
if(null != mString && mString.length>0)
setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mString ));
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
listString = new LinkedList<String>();
updateUI();
}
}
我打算做的是从另一个线程调用UI更新。
这将是我上面的代码文件的修改。
private class HelperClass implements Runnable{
public void run() {
performSomeCalculation();
}
/*
* This code will populate the list as it is executed.
* As and when there is a new element in the list the UI is updated.
*/
public void performSomeCalculation(){
//update list String
updateUI();
}
/*
/*
*
* The new update onCreate method calling another thread that populates the UI thread
*
*/
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
listString = new LinkedList<String>();
//updateUI();
Thread thread = new Thread(new HelperClass());
thread.start();
}
你可以在上面的代码中看到我创建了一个HelperClass来执行一些计算,因为当计算线程输出时它应该更新UI线程。
我正在努力让它发挥作用,如果有人发现plz更新我的帖子。
提前致谢。
答案 0 :(得分:0)
如果您想要更新UI的线程阻塞操作(例如从Internet下载图像),您应该使用Handler
类来创建回调。
http://developer.android.com/reference/android/os/Handler.html
Handler
类将绑定到UI线程,并允许您将实现Runnable
接口的对象发布到队列中,以便在正确的线程中执行。
但是,我不确定是否有可能从给定的代码中实现您的目标。关于环境和期望行为的一些进一步信息将会有所帮助。
使用Handler
更新UI的典型实现,基于我自己的应用程序中下载静态地图并更新UI的代码,可能如下所示:
public class HandlerExample extends Activity {
/**
* Handler to allow other threads to send executable messages (in the form
* of Runnable objects) to the main UI thread. This is used to download the
* static image in a separate thread to stop the UI from blocking
*/
private final Handler handler = new Handler();
/**
* Runnable implementation that, in conjunction with handler, displays a
* given static map in the ImageView
*/
private final UpdateStaticMap updateStaticMap = new UpdateStaticMap();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//... other initialisation
// This object implements Runnable and is used to post our update to the Handler
updateStaticMap.setImageView((ImageView)findViewById(R.id.venuedetail_mapimage));
// Then we pass the Runnable object, the Handler, and all the data we
// need to get the
// map into a Thread subclass to avoid blocking the UI thread
// Note, the thread is started in the constructor so we don't worry about it here
new MapGetter(handler, updateStaticMap);
}
/**
* This private class extends Thread to handle the downloading of the static
* map separately from the main UI thread to avoid
* blocking it. It uses the Handler to trigger the UI thread to update the
* ImageView when it's finished by passing updateStaticMap as a message
* (it's a Runnable, thus will be executed by the handler in the UI thread).
* This is necessary as only the thread that created the View components can
* edit them.
*
* @author Chris Bunney
*
*/
private class MapGetter extends Thread {
/**
* The Handler associated with the UI thread. Used to pass the map back
* to the UI thread
*/
private final Handler handler;
/**
* The Runnable implementation used to wrap the bitmap when passing it
* back to the UI thread via handler
*/
private final UpdateStaticMap updateStaticMap;
/**
*
*
* @param handler
* Handler for the UI thread so the MapGetter can update the
* ImageView with the map
* @param updateStaticMap
* Runnable object that is used to send the map back to and
* update the UI
**/
public MapGetter(Handler handler, UpdateStaticMap updateStaticMap) {
this.handler = handler;
this.updateStaticMap = updateStaticMap;
this.start();
}
/**
* Obtains the Static Map and passes it back to the main
* UI thread to be displayed
*/
@Override
public void run() {
//Note, the getImage() method is just a stand in for whatever code you need to get the image
updateStaticMap.setBitmap(getImage()));
//Now our Runnable object has all the data it needs, we post it back to the Handler
handler.post(updateStaticMap);
}
}
/**
* This class implements the Runnable interface. It acts a message to be
* delivered to the UI thread. This class updates a given ImageView with a
* given Bitmap. The ImageView and Bitmap form the payload of the message.
* This class is necessary because only the thread that created a View can
* alter it, so the object is passed to the correct thread and executed by
* it.
*
* @author Chris Bunney
*
*/
private class UpdateStaticMap implements Runnable {
/**
* The ImageView to target when setting the bitmap
*/
private ImageView mapImage;
/**
* The Bitmap to update the ImageView with
*/
private Bitmap bm;
/**
* Inserts the Bitmap, bm, into the ImageView, mapImage
*
*/
@Override
public void run() {
mapImage.setImageBitmap(bm);
Log.d(TAG, "run: Static Map Updated");
}
/**
* Accessor method to insert the bitmap payload into the message
*
* @param bm
* Static map to be displayed in the UI
*/
public void setBitmap(Bitmap bm) {
this.bm = bm;
Log.d(TAG, "setBitmap: Bitmap updated");
}
/**
* Accessor method to associate the object with a particular ImageView
*
* @param mapImage
* ImageView that the map should be displayed in
*/
public void setImageView(ImageView mapImage) {
this.mapImage = mapImage;
Log.d(TAG, "setImageView: ImageView updated");
}
}
}
答案 1 :(得分:0)
最后借助Chris的代码解决了我自己的问题。
Plz参考Chris的方法描述代码。
Plz纠正我的任何会议损失。
布局文件内容如下。
<ListView
android:id="@+id/list"
android:layout_span="1"
android:layout_width="324px"
android:layout_height="348px"/>
java文件内容如下。
import java.util.LinkedList;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class TestApp extends Activity {
private final Handler handler = new Handler();
private final UILoadingHelperClass uiLoadingThread = new UILoadingHelperClass();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
uiLoadingThread.setListView(R.id.list);
new DataLoadingThread(handler, uiLoadingThread);
}
private class DataLoadingThread extends Thread {
int count = 0;
LinkedList<String> linkedList = null;
private final Handler handler;
private final UILoadingHelperClass uiLoadingThread;
public DataLoadingThread(Handler handler, UILoadingHelperClass uiLoadingThread) {
this.handler = handler;
this.uiLoadingThread = uiLoadingThread;
this.start();
}
@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(null == linkedList)
linkedList = new LinkedList<String>();
linkedList.add("Test "+count++);
int i=0;
String[] strings = new String[linkedList.size()];
for(String string : linkedList)
strings[i++]=string;
uiLoadingThread.setSttrings(strings);
handler.post(uiLoadingThread);
}
}
}
private class UILoadingHelperClass implements Runnable {
private ListView listView = null;
private String[] strings = null;
public void setSttrings(String[] strings){
this.strings = strings;
}
public void setListView(int id){
listView = (ListView)findViewById(id);
}
public void run() {
if(null != strings && strings.length>0)
listView.setAdapter(new ArrayAdapter<String>(TestApp.this,android.R.layout.simple_list_item_1,strings));
}
}
}