我正在尝试从api提取数据,但遇到以下错误,我无法找出问题出在哪里,我正在对fetech数据使用单独的UI线程,然后应用也会崩溃。
2020-02-20 17:20:01.088 22802-22802/com.example.flypped E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.flypped, PID: 22802
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
at com.android.org.conscrypt.Platform.blockGuardOnNetwork(Platform.java:415)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.read(ConscryptFileDescriptorSocket.java:560)
at okio.InputStreamSource.read(Okio.kt:102)
at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:159)
at okio.RealBufferedSource.request(RealBufferedSource.kt:62)
at okio.RealBufferedSource.require(RealBufferedSource.kt:55)
at okio.RealBufferedSource.readHexadecimalUnsignedLong(RealBufferedSource.kt:299)
at okhttp3.internal.http1.Http1ExchangeCodec$ChunkedSource.readChunkSize(Http1ExchangeCodec.kt:450)
at okhttp3.internal.http1.Http1ExchangeCodec$ChunkedSource.read(Http1ExchangeCodec.kt:429)
at okhttp3.internal.connection.Exchange$ResponseBodySource.read(Exchange.kt:279)
at okio.RealBufferedSource.select(RealBufferedSource.kt:93)
at okhttp3.internal.Util.readBomAsCharset(Util.kt:256)
at okhttp3.ResponseBody.string(ResponseBody.kt:187)
at com.example.flypped.MainActivity$2$1.run(MainActivity.java:110)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7156)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
Suppressed: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
at com.android.org.conscrypt.Platform.blockGuardOnNetwork(Platform.java:415)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.read(ConscryptFileDescriptorSocket.java:560)
at okio.InputStreamSource.read(Okio.kt:102)
at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:159)
at okio.RealBufferedSource.request(RealBufferedSource.kt:62)
at okio.RealBufferedSource.require(RealBufferedSource.kt:55)
at okio.RealBufferedSource.readHexadecimalUnsignedLong(RealBufferedSource.kt:299)
at okhttp3.internal.http1.Http1ExchangeCodec$ChunkedSource.readChunkSize(Http1ExchangeCodec.kt:450)
at okhttp3.internal.http1.Http1ExchangeCodec$ChunkedSource.read(Http1ExchangeCodec.kt:429)
at okhttp3.internal.Util.skipAll(Util.kt:337)
at okhttp3.internal.Util.discard(Util.kt:358)
at okhttp3.internal.http1.Http1ExchangeCodec$ChunkedSource.close(Http1ExchangeCodec.kt:471)
at okio.ForwardingSource.close(ForwardingSource.kt:34)
at okhttp3.internal.connection.Exchange$ResponseBodySource.close(Exchange.kt:306)
at okio.RealBufferedSource.close(RealBufferedSource.kt:461)
at kotlin.io.CloseableKt.closeFinally(Closeable.kt:56)
at okhttp3.ResponseBody.string(ResponseBody.kt:186)
下面是我的代码:
XML代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/drawer_layout"
android:fitsSystemWindows="true"
tools:context=".MainActivity"
tools:openDrawer="start">
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/bottomBar"
android:layout_gravity="bottom"
app:menu="@menu/bottom_menu"
android:background="#fff"
app:itemIconTint="@drawable/nav_check"
app:itemTextColor="@drawable/nav_check"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:id="@+id/nav_view">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
layout="@layout/nav_header"
android:id="@+id/header"/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/header"
android:id="@+id/menuRecycler"
android:layout_marginTop="20dp"/>
</RelativeLayout>
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
Java代码:
private void getMenuData(){
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20,TimeUnit.SECONDS)
.build();
Request request = new Request.Builder().url(URL).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull final Response response) throws IOException {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
JSONArray jsonArray = new JSONArray(response.body().string());
// Log.d("array", String.valueOf(jsonArray));
if(jsonArray.length() > 0){
for(int i=0;i<jsonArray.length();i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String str1 = jsonObject.getString("name");
String str2 = jsonObject.getString("term_id");
MenuModel model = new MenuModel(str1,str2);
list.add(model);
}
adapter = new MenuAdapter(list,getApplicationContext());
menuRecycler.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
public void onFailure(@NotNull Call call, @NotNull final IOException e) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
});
}
日志猫在下面的行中显示错误
JSONArray jsonArray = new JSONArray(response.body().string());
请让我知道我做错了什么,我们将不胜感激。
谢谢
答案 0 :(得分:0)
将您的api调用放入运行块中。
build
答案 1 :(得分:0)
回调在后台线程上运行。如果要立即在UI中处理某些内容,则需要发布到主线程中。
private void hitApi(HttpCallBacks cb){
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull final Response response) throws IOException {
mainHandler.post(new Runnable() {
@Override
public void run() {
cb.onSuccess(null, throwable);
}
});
}
@Override
public void onFailure(@NotNull Call call, @NotNull final IOException e) {
mainHandler.post(new Runnable() {
@Override
public void run() {
cb.onFailure( throwable);
}
});
}
});
}
}
interface HttpCallBacks{
void onFailure(Throwable t);
void onSuccess(Response r);
}
答案 2 :(得分:0)
在这里尝试这段代码,看看是否有帮助。我正在利用主线程上的处理程序,因为主要问题是您不能直接使用UI线程作为响应,也不能在后台线程中更新UI。
您需要声明另外2个全局变量,例如:
Handler mainHandler = new Handler(Looper.getMainLooper());
String mStringResponse;
并将您的方法编写为:
private void getMenuData(){
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20,TimeUnit.SECONDS)
.build();
Request request = new Request.Builder().url(URL).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull final Response response) throws IOException {
mStringResponse = String.valueOf(response.body());
mainHandler.post(new Runnable() {
@Override
public void run() {
try {
JSONArray jsonArray = new JSONArray(mStringResponse);
if (jsonArray.length() > 0) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String str1 = jsonObject.getString("name");
String str2 = jsonObject.getString("term_id");
MenuModel model = new MenuModel(str1, str2);
list.add(model);
}
adapter = new MenuAdapter(list, getApplicationContext());
menuRecycler.setAdapter(adapter);
}
}catch (JSONException e) { }
}
});
}
@Override
public void onFailure(@NotNull Call call, @NotNull final IOException e) {
mainHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
});
}
UI更改应以这种方式工作,不确定适配器的限制,但是请尝试并检查是否有帮助。