2012-06-08 64 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