今天,应用Android Studio连接Api Store 天气获取Json消息,配置成功后报出android.os.NetworkOnMainThreadException错误解决方法如下:
未修改前 MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView tv;
public static String request(String httpUrl, String httpArg) {
BufferedReader reader = null;
String result = null;
StringBuffer sbf = new StringBuffer();
httpUrl = httpUrl + "?" + httpArg;
try {
URL url = new URL(httpUrl);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("GET");
// 填入apikey到HTTP header
connection.setRequestProperty("apikey", "3ace713028f4abe9de414dc98ade98bf");
connection.connect();
InputStream is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sbf.append(strRead);
sbf.append("\r\n");
System.out.println("我执行了!!!!");
}
reader.close();
result = sbf.toString();
System.out.println("我执行了!!!!");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onclick(View view){
tv = (TextView) findViewById(R.id.textView);
String httpUrl = "http://apis.baidu.com/thinkpage/weather_api/suggestion";
String httpArg = "location=beijing&language=zh-Hans&unit=c&start=0&days=3";
String jsonResult = request(httpUrl, httpArg);
tv.setText(jsonResult);
}
修改后 MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView tv;
public static String request(String httpUrl, String httpArg) {
BufferedReader reader = null;
String result = null;
StringBuffer sbf = new StringBuffer();
httpUrl = httpUrl + "?" + httpArg;
try {
URL url = new URL(httpUrl);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("GET");
// 填入apikey到HTTP header
connection.setRequestProperty("apikey", "3ace713028f4abe9de414dc98ade98bf");
connection.connect();
InputStream is = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sbf.append(strRead);
sbf.append("\r\n");
System.out.println("我执行了!!!!");
}
reader.close();
result = sbf.toString();
System.out.println("我执行了!!!!");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.penaltyLog()
.penaltyDeath()
.build());
}
public void onclick(View view){
tv = (TextView) findViewById(R.id.textView);
String httpUrl = "http://apis.baidu.com/thinkpage/weather_api/suggestion";
String httpArg = "location=beijing&language=zh-Hans&unit=c&start=0&days=3";
String jsonResult = request(httpUrl, httpArg);
tv.setText(jsonResult);
}
即在onCreat方法中加入StrictMode模式,网络上找到原因如下:
1.在2.3版本以后加入了StrictMode类,而在3.0在网络上能感觉到有更加严格的限制,更多的查询API上的StrictMode ;
2.使用的时候只需要在你项目运行的入口Activity的OnCreate中放入这段代码,那么整个项目程序都有用。不需要每个Activity里面加入。
3.StrictMode类一般是用来调试的,在程序运行中会打印很多消息,那是告诉你你的项目程序需要改进的地方。在Android项目中,最好的是让界面与后台装载程序分开来。总之,如果你的程序代码非常符合Android规范要求,那么你完全可以不使用上面的代码…
4.网络请求的相关操作在主线程中不被允许,应该在子线程中完成,因为整个网络请求可能会超过主线程的响应时间,从而引发程序崩溃。解决思路:新建Thread子线程在子线程中完成。