[英]ListView does not refresh from AsyncTask
我制作了一個應用程序,每5秒刷新一次WiFi狀態。 這是主要活動
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;
}
您應該使用AsyncTask的以下方法更新列表視圖。
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
請記住, startScan()
立即返回,並且當結果可用時異步startScan()
結果可用性。 因此,當您在調用startscan()
之后直接讀取掃描結果時,結果很可能不存在,因此您正在向適配器發送空白信息。
因此,這涵蓋了為什么您的視圖沒有刷新的原因。 因此,如何確保僅在結果可用時才讀取結果。 請參閱下面的建議。
最好使用BroadcastReceiver接收掃描結果。 注冊參加SCAN_RESULTS_AVAILABLE_ACTION
因此,您可以以異步方式運行掃描,但不要從那里進行任何刷新,只需使用它即可保持循環運行。 如果需要,您也可以只使用一個線程。
要進行更新,只需從接收者回撥回您在其中讀取掃描結果的活動。
我還注意到,您正在onCreate
中調用startscan()
,然后在創建Async任務后再次調用startscan()
。 這樣做有什么意義。
如果我正確理解您的問題。
假設:1.您正在更新適配器中的值
解:
要刷新列表視圖,您需要做的是:
your_list_adapter.notifyDataSetChanged();
我希望這有幫助..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.