ListView不会从AsyncTask刷新

时间:2012-06-08 09:46:12

标签: java android listview android-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;
}

3 个答案:

答案 0 :(得分:0)

您应该使用AsyncTask的以下方法来更新列表视图。

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

答案 1 :(得分:0)

请记住,startScan()会立即返回,并且当结果可用时,结果的可用性将异步显示。因此,当您在调用startscan()后直接读取扫描结果时,结果很可能不存在,因此您将向适配器发送空白信息。

因此,这涵盖了为什么您的观点不令人耳目一新。那么如何确保只在可用时才读取结果。见下面的建议。

最好使用BroadcastReceiver接收扫描结果。注册SCAN_RESULTS_AVAILABLE_ACTION

所以你在异步中运行扫描,但不要从那里做任何刷新只是使用它保持你的循环运行。如果你愿意的话,你也可以只使用一个线程。

要更新,只需从接收器回拨给您阅读扫描结果的活动。

我还注意到您正在startscan()中调用onCreate,然后在创建异步任务后直接再次执行相同操作。这样做有什么意义。

答案 2 :(得分:0)

如果我理解你的问题。

假设: 1.您正在更新适配器中的值

解决方案:

要刷新列表视图,您只需:

your_list_adapter.notifyDataSetChanged();

我希望这有帮助..