============问题描述============
当我在Handler进行频繁更新界面的时候 发现SimpleAdapter不能自动更新 甚至button也不更新了
public class CreateActivity extends Activity{
protected static CharSequence text = "Waiting Range";
public static MobilocMaster mobilocMaster = new MobilocMaster();
public static MobilocAnchor mobilocAnchor = new MobilocAnchor();
public static LoopThread lt;
Button mButton;
static boolean started = false;
Handler handler;
//创建自动更新的List列表相关定义
SimpleAdapter adapter ;
List<Map<String,?>> data = new ArrayList<Map<String,?>>();
Map<String, String> map = new HashMap<String, String>();
Hashtable<String,myAnchorInfo> tempAnchor = new Hashtable<String,myAnchorInfo>();
myAnchorInfo tempInfo = new myAnchorInfo();
AnchorInfo myAnchor;
AnchorPair myAnchorPair;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.create);
ini(!started);
mButton = (Button) findViewById(R.id.button);
mButton.setText(text);
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent1 = new Intent(CreateActivity.this,CoordinateActivity.class);
startActivity(intent1);
}
});
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
text = "Waiting Range";
mButton.setEnabled(false);
mButton.setText(text);
data.clear();
Hashtable<String,myAnchorInfo> temp = (Hashtable<String,myAnchorInfo>)msg.obj;
Enumeration t = temp.keys();
while(t.hasMoreElements()) {
String t1 = (String)t.nextElement();
myAnchorInfo myi = (myAnchorInfo)temp.get(t1);
map = new HashMap<String, String>();
map.clear();
map.put("name", myi.name);
map.put("ip", myi.ip);
map.put("range", myi.range);
data.add(map);
}
adapter.notifyDataSetChanged();
System.out.println(data.toString()+"Data的数据[test]");
System.out.println("Handler更新界面--->Waiting Range[test]");
break;
case 2:
text = "Look Position";
mButton.setEnabled(true);
mButton.setText(text);
data.clear();
Hashtable<String,myAnchorInfo> temp1 = (Hashtable<String,myAnchorInfo>)msg.obj;
System.out.println(msg.obj.toString()+"Message的信息[test]");
Enumeration t2 = temp1.keys();
while(t2.hasMoreElements()) {
String t3 = (String)t2.nextElement();
myAnchorInfo myi = (myAnchorInfo)temp1.get(t3);
map = new HashMap<String, String>();
map.clear();
map.put("name", myi.name);
map.put("ip", myi.ip);
map.put("range", myi.range);
data.add(map);
}
adapter.notifyDataSetChanged();
System.out.println(data.toString()+"Data的数据[test]");
System.out.println("Handler更新界面--->Look Position[test]");
break;
}
}
};
}
初始化更新的时候
void ini(Boolean flag){
if(flag)
{
Intent intent = getIntent();
String myname = intent.getStringExtra("myName");
rangingSettings();
mobilocAnchor.setAnchorName(myname);
mobilocMaster.start();
mobilocAnchor.start();
ListView lv = (ListView) findViewById(R.id.list1);
String[] from = new String[]{"name" , "ip", "range"};
int[] to = new int[]{R.id.person_name , R.id.person_ip , R.id.person_range};
adapter = new SimpleAdapter(this, data,R.layout.child_create, from,to);
lv.setAdapter(adapter);
started = true;
lt = new LoopThread();
lt.start();
}
}
更新数据的线程
class LoopThread extends Thread{
Boolean flag = true;
public void run() {
while(true) {
try {
Thread.sleep(3000);
tempAnchor.clear();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(true){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(mobilocAnchor.getMyAddress()!= null){
myAnchor = new AnchorInfo(mobilocAnchor.getMyAddress());
break;
}
}
Enumeration akey = MobilocMaster.anchorTable.keys();
Enumeration rkey = MobilocMaster.rangingTable.keys();
while(akey.hasMoreElements()) {
AnchorNetInfo key1 = (AnchorNetInfo)akey.nextElement();
AnchorInfo ai = (AnchorInfo)MobilocMaster.anchorTable.get(key1);
if(myAnchor.getHostString().contains(ai.getHostString()))
continue;
tempInfo.setAnchorInfo(ai.getName(), ai.getIP());
myAnchorPair = new AnchorPair(myAnchor.getHostString(),ai.getHostString());
if(LocationAnchor.readyForRanging){
tempInfo.setRange(MobilocAnchor.rangingTable.get(myAnchorPair).getDistance());
tempAnchor.put(ai.getName(),tempInfo);
flag = false;
}
else{
tempInfo.setRange("Ranging");
tempAnchor.put(ai.getName(),tempInfo);
}
}
if(flag){
Message message = new Message();
message.what = 1;
message.obj = tempAnchor;
System.out.println(message.obj.toString()+"主线程Message信息[test]");
handler.sendMessage(message);
}
else
{
Message message1 = new Message();
message1.what = 2;
message1.obj = tempAnchor;
handler.sendMessage(message1);
System.out.println(message1.obj.toString()+"主线程Message1信息[test]");
flag = true;
}
}
}
}
自己定义的结构体
class myAnchorInfo{
String name;
String range;
String ip;
public void setAnchorInfo(String name,String ip){
this.name = name;
this.ip = ip;
}
public void setRange(float ft){
this.range = (float)(Math.round(ft*100))/100+"";
}
public void setRange(String range){
this.range = range;
}
}
============解决方案1============
tempAnchor在两个线程里访问,没有做线程同步保护。
============解决方案2============
引用 3 楼 u010285208 的回复:
Quote: 引用 2 楼 svenwang 的回复:
tempAnchor在两个线程里访问,没有做线程同步保护。
这个怎么才能线程保护呢
就算是线程安全 为什么Button 也不能更新呢 谢谢
这样线程保护:
Hashtable<String,myAnchorInfo> temp = (Hashtable<String,myAnchorInfo>)msg.obj;
synchronized(temp) {
// 访问temp
}
synchronized(tempAnchor) {
// 访问tempAnchro
}
你做了线程保护的代码是怎么样的?
以下这段代码好像也有问题,如果getMyAddress返回null就死循环了。你可以在UI不能更新的时候,在子线程里下几个断点看看能不能执行到。
while (true) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (mobilocAnchor.getMyAddress() != null) {
myAnchor = new AnchorInfo(mobilocAnchor.getMyAddress());
break;
}
}
============解决方案3============
问题出在哪,调试下就知道了,看你消息发出去没,发出去后更新UI的操作执行了没