我添加了AsyncTask以将网络操作卸载到后台线程。我需要确保UI操作在UI线程上。所以我想在我的Activity中使用runOnUiThread()。
感谢您的帮助
WifiApManager
public class WifiApManager {
private final WifiManager mWifiManager;
public WifiApManager(Context context) {
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
}
public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
try {
if (enabled) { // disable WiFi in any case
mWifiManager.setWifiEnabled(false);
}
Method method = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
return (Boolean) method.invoke(mWifiManager, wifiConfig, enabled);
} catch (Exception e) {
Log.e(this.getClass().toString(), "wifi", e);
return false;
}
}
public WIFI_AP_STATE getWifiApState() {
try {
Method method = mWifiManager.getClass().getMethod("getWifiApState");
int tmp = ((Integer)method.invoke(mWifiManager));
// Fix for Android 4
if (tmp > 10) {
tmp = tmp - 10;
}
return WIFI_AP_STATE.class.getEnumConstants()[tmp];
} catch (Exception e) {
Log.e(this.getClass().toString(), "wifi", e);
return WIFI_AP_STATE.WIFI_AP_STATE_FAILED;
}
}
public boolean isWifiApEnabled() {
return getWifiApState() == WIFI_AP_STATE.WIFI_AP_STATE_ENABLED;
}
public WifiConfiguration getWifiApConfiguration() {
try {
Method method = mWifiManager.getClass().getMethod("getWifiApConfiguration");
return (WifiConfiguration) method.invoke(mWifiManager);
} catch (Exception e) {
Log.e(this.getClass().toString(), "wifi", e);
return null;
}
}
public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
try {
Method method = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
return (Boolean) method.invoke(mWifiManager, wifiConfig);
} catch (Exception e) {
Log.e(this.getClass().toString(), "wifi", e);
return false;
}
}
public ArrayList<ClientScanResult> getClientList(boolean onlyReachables) {
return getClientList(onlyReachables, 10);
}
public ArrayList<ClientScanResult> getClientList(boolean onlyReachables, int reachableTimeout) {
BufferedReader br = null;
ArrayList<ClientScanResult> result = null;
try {
result = new ArrayList<ClientScanResult>();
br = new BufferedReader(new FileReader("/proc/net/arp"));
String line;
while ((line = br.readLine()) != null) {
String[] splitted = line.split(" +");
if ((splitted != null) && (splitted.length >= 4)) {
// Basic sanity check
String mac = splitted[3];
if (mac.matches("..:..:..:..:..:..")) {
boolean isReachable = InetAddress.getByName(splitted[0]).isReachable(reachableTimeout);
if (!onlyReachables || isReachable) {
result.add(new ClientScanResult(splitted[0], splitted[3], splitted[5], isReachable));
}
}
}
}
} catch (Exception e) {
Log.e(LOGTAG, e.toString());
} finally {
try {
br.close();
} catch (IOException e) {
Log.e(LOGTAG, e.toString());
}
}
return result;
}
}
connect.java
public class connect extends Activity{
WifiApManager wifiApManager;
TextView tv;
Button scan;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.connect);
tv =(TextView) findViewById(R.id.iptv);
new scan().execute();
}
public class scan extends AsyncTask<String, Integer, String> {
public Object WIFI_SERVICE;
@Override
protected void onProgressUpdate(Integer...integers) {
ArrayList<ClientScanResult> clients = wifiApManager.getClientList(false);
tv.setText("WifiApState: " + wifiApManager.getWifiApState() + "\n\n");
tv.append("Clients: \n");
for (ClientScanResult clientScanResult : clients) {
tv.append("####################\n");
tv.append("IpAddr: " + clientScanResult.getIpAddr() + "\n");
tv.append("Device: " + clientScanResult.getDevice() + "\n");
tv.append("HWAddr: " + clientScanResult.getHWAddr() + "\n");
tv.append("isReachable: " + clientScanResult.isReachable()+ "\n");
}
}
@Override
protected void onPostExecute(String result){
tv.setText(result);
}
@Override
protected String doInBackground(String... params) {
wifiApManager = new WifiApManager(this);
// the above line shows a Error
return null;
}
}
}
修改
我想在TextView中显示已处理的文本
class scan extends AsyncTask<String, Void, Void> {
public Context context;
ArrayList<ClientScanResult> clients;
public scan(Context c) // constructor to take Context
{
context = c; // Initialize your Context variable
}
protected Void doInBackground(String... params) {
wifiApManager = new WifiApManager(context); // use the variable here
clients = wifiApManager.getClientList(false);
return null;
}
}
protected void onPostExecute(Void result){
ArrayList<ClientScanResult> clients;
tv.setText("WifiApState: " + wifiApManager.getWifiApState() + "\n\n");
tv.append("Clients: \n");
for (ClientScanResult clientScanResult : clients)//showin error in clients
{
tv.append("####################\n");
tv.append("IpAddr: " + clientScanResult.getIpAddr() + "\n");
tv.append("Device: " + clientScanResult.getDevice() + "\n");
tv.append("HWAddr: " + clientScanResult.getHWAddr() + "\n");
tv.append("isReachable: " + clientScanResult.isReachable()+ "\n");
}
}
}
答案 0 :(得分:0)
您不应该访问doInBackground
中的任何UI元素,此方法在后台线程中运行。你应该做的是覆盖onPostExecute()
方法并访问那里的TextView
。 onPostExecute
在UI线程中运行,因此您无需致电runOnUiThread()
答案 1 :(得分:0)
我添加了AsyncTask以将网络操作卸载到后台线程。我需要确保UI操作在UI线程上。所以我想在我的Activity中使用runOnUiThread()。
唉!没有!!! AsyncTask
的每个方法都在UI Thread
上运行,但doInBackground()
除外。在doInBackground()
中进行网络操作,并通过UI
调用onPostExecute()
来更新onProgressUpdate()
或publishProgress()
中的doInBackground()
。
请勿将runOnUiThread()
与AsyncTask
一起使用。我至少知道没有理由将其与AsyncTask
一起使用,因为它具有已经在UI Thread
上运行的方法。我从来没有看到它做任何事情,但会造成麻烦。
您可以从publishProgress()
致电loop
并更新TextView
中的onProgressUpdate()
或将值添加到ArrayList
并更新onProgressUpdate()
}}
Please read the docs several times。 AsyncTask
一开始有点棘手,但是一旦你了解它做了什么,它就会变得很美好。
修改强>
创建AsyncTask
的实例并将Activity Context
传递给它
Scan myScan = new scan(this); // pass the context to the constructor
myScan.execute();
然后在AsyncTask
中创建一个构造函数,让它接受Context
。
public class scan extends AsyncTask<String, Integer, String>
{
public Object WIFI_SERVICE;
public Context context; // Context variable
public scan(Context c) // constructor to take Context
{
context = c; // intialize your Context variable
}
现在使用该变量
@Override
protected String doInBackground(String... params)
{
wifiApManager = new WifiApManager(context); // use the variable here
return null;
}
另一个编辑
class scan extends AsyncTask<String, Void, Void> {
ArrayList<ClientScanResult> clients;
Context context;
...
then initialize your `clients` in `doInBackground()`
clients = wifiApManager.getClientList(false);
将onPostExecute()
更改为不接受任何内容
protected void onPostExecute(Void result){
并将您的代码更新为TextView
。