问题
My App shows a NetworkOnMainThreadException
in the Log Cat.
So I found the Asynctask Method to offload network operations to a background thread.
After adding the AsyncTask.It shows ViewRootImpl$CalledFromWrongThreadException
.So i have to use onPostExecute
.
I learnt the Asyntack
Docs & tried.Now i got Stuck it is not Returning the correct output.I don't know whether i declared it under the respective Method's.
I want to display the processed Text in the Textview
tv
So Help me in the Right Direction :)
Thanks for your Help ...
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);
scan myScan = new scan(this); // pass the context to the constructor
myScan.execute();
}
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");
}
}
}
Note: It shows a error in connect.java on onPostExecute Method in Clients Variable.
回答1:
in your onPostExecute(...) you have
ArrayList<ClientScanResult> **clients**;
and then
for (ClientScanResult clientScanResult : **clients**) //showin error in clients
clients is null therefore the loop is never executed. you don't need to define a new ArrayList since you already have one defined as a global variable in the scan class
A better way to do this is to set the return type of doInBackground to ArrayList< ClientScanResult> and then you have onPostExecute take an ArrayList< ClientScanResult>
class scan extends AsyncTask<Void, Void, ArrayList<ClientScanResult>> {
protected ArrayList<ClientScanResult> doInBackground(Void... params) {
wifiApManager = new WifiApManager(context); // use the variable here
return wifiApManager.getClientList(false);
}
protected void onPostExecute(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");
}
}
来源:https://stackoverflow.com/questions/20845369/how-to-troubleshoot-asynctask