SimpleAdapter不能自动更新 求解释
============问题描述============
当我在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============
这样线程保护:
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的操作执行了没