2012-06-08 61 views
0

我做了一個應用程序刷新每5秒的WiFi狀態。這裏的主要活動ListView不刷新從AsyncTask

public class WiFiList extends Activity { 
/** Called when the activity is first created. */ 

private String screen; 
private ListView nets; 
private WifiManager wifi; 
private NetAdapter nAdap; 
SharedPreferences getPrefs; 
Updater skaner; 
List<ScanResult> scan; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); 
    String screen = getPrefs.getString("start", "list"); 
    wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 
    if(screen.equals("list")){ 
     setContentView(R.layout.main); 
     nets = (ListView) findViewById(R.id.lvNets); 
     wifi.startScan(); 
     scan = new ArrayList<ScanResult>(); 
     nAdap = new NetAdapter(getApplicationContext(), scan); 
     nets.setAdapter(nAdap); 
     nAdap.notifyDataSetChanged(); 
    } 
    skaner = new Updater(); 
    skaner.execute(); 
} 

public void refresh(){ 
    nAdap.notifyDataSetChanged(); 
} 

class Updater extends AsyncTask<Void, Void, Void>{ 
    @Override 
    protected Void doInBackground(Void... params) { 
     // doSomething(); 
     while(wifi.isWifiEnabled()){ 
      int waiter = getPrefs.getInt("intervals", 5) * 1000; 
      wifi.startScan(); 
      scan = wifi.getScanResults(); 
      publishProgress(); 
      try { 
       Thread.sleep(waiter); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      if(isCancelled()){ 
       break; 
      } 
     } 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(Void... values) { 
     // TODO Auto-generated method stub 
     super.onProgressUpdate(values); 
     refresh(); 
    } 
} 

@Override 
public void onBackPressed() { 
    // TODO Auto-generated method stub 
    skaner.cancel(true); 
    super.onBackPressed(); 
} 

但是,ListView不刷新。當我運行調試器時,我看到調用了refresh(),並且每次都有不同的值。什麼阻止它刷新?當我把它掃描網絡中onCreate(),它們出現在名單上,所以我認爲適配器是正確的,但這裏的代碼反正:

public class NetAdapter extends BaseAdapter{ 

private LayoutInflater mInflater; 
List<ScanResult> res; 

public NetAdapter(Context context, List<ScanResult> l){ 
    mInflater = LayoutInflater.from(context); 
    res = l; 
} 

@Override 
public int getCount() { 
    // TODO Auto-generated method stub 
    return res.size(); 
} 

@Override 
public Object getItem(int arg0) { 
    // TODO Auto-generated method stub 
    return res.get(arg0); 
} 

@Override 
public long getItemId(int arg0) { 
    // TODO Auto-generated method stub 
    return arg0; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // TODO Auto-generated method stub 
    ViewHolder holder; 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.netitem, null); 
     holder = new ViewHolder(); 
     holder.tvName = (TextView) convertView.findViewById(R.id.tvName); 
     holder.tvFreq = (TextView) convertView.findViewById(R.id.tvFreq); 
     holder.tvRssi = (TextView) convertView.findViewById(R.id.tvRssi); 
     holder.ivState = (ImageView) convertView.findViewById(R.id.ivSignal); 
     convertView.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 
    holder.tvName.setText(res.get(position).SSID +" (" + res.get(position).BSSID + ")"); 
    holder.tvFreq.setText(Integer.toString(res.get(position).frequency)+"MHz"); 
    holder.tvRssi.setText(Integer.toString(res.get(position).level)+"dBm"); 
    holder.ivState.setImageResource(R.drawable.ic_launcher); 
    return convertView; 
} 

static class ViewHolder{ 
    TextView tvName; 
    TextView tvFreq; 
    TextView tvRssi; 
    ImageView ivState; 
} 
+0

嘗試使用'invalidateViews()' – Sajmon

回答

0

你應該使用下面的AsyncTask的方法來更新列表視圖。

protected void onPostExecute(Long result) { 
     showDialog("Downloaded " + result + " bytes"); 
    } 
+0

只有在doInBackground完成後才能運行?在我的應用程序中它不斷運行。 – hubert

+0

DynamicMind是正確的,你需要一個'onPostExecute'方法,你應該調用你自己的接口的'onCompleteTask'方法,它不是強制性的,但它有助於模塊化,你會有一個更好的概述。來自你的活動調用你的Custom'AsyncTask'應該實現你應該有可用數據的'onCompleteTask'。如果不是這樣的話,你可以隨時開發你自己的事件及其關聯的監聽器,等待它可用。 –

0

請記住,立即startScan()收益和結果的有效性是由異步知道當結果是可用的。所以當您在撥打startscan()之後直接讀取掃描結果時,結果很可能不存在,因此您會向適配器發送空白信息。

因此,這涵蓋了爲什麼你的觀點不清爽。所以你如何確保你只有在結果可用時纔讀取結果。見下面的建議。

使用BroadcastReceiver接收掃描結果會更好。註冊SCAN_RESULTS_AVAILABLE_ACTION

所以你在你的異步中運行掃描,但不要從那裏做任何刷新,只是使用它來保持你的循環運行。如果你願意的話,你也可以只使用一個線程。

若要更新,只需將您的接收器回撥回到您讀取掃描結果的位置即可。

我還注意到,您在onCreate中調用startscan(),然後在創建異步任務之後直接再次執行相同操作。這麼做的意義何在?

+0

正如我所說。我檢查了調試器,並且每次列表都充滿了正確的數據。 – hubert

0

如果我正確理解你的問題。

假設: 1.You在適配器更新值

解決方案:

要刷新列表視圖,所有你需要做的是:

your_list_adapter.notifyDataSetChanged(); 

我希望這有助於..

+0

這就是我在行'nAdap.notifyDataSetChanged()' – hubert