我在 Android 预发布报告中收到有关崩溃的报告。在我的模拟器和我拥有的三个物理测试设备上一切正常。报错如下
致命异常:java.lang.RuntimeException
执行 doInBackground() 时发生错误
android.os.AsyncTask$3.done (AsyncTask.java:353)
java.util.concurrent.FutureTask.finishCompletion (FutureTask.java:383)
java.util.concurrent.FutureTask.setException (FutureTask.java:252)
java.util.concurrent.FutureTask.run (FutureTask.java:271)
android.os.AsyncTask$SerialExecutor$1.run (AsyncTask.java:245)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1162)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:636)
java.lang.Thread.run (Thread.java:764)
由java.lang.IllegalStateException引起
预期为 BEGIN_ARRAY,但在第 1 行第 2 列路径 $ 处为 BEGIN_OBJECT
com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read (CollectionTypeAdapterFactory.java)
retrofit2.converter.gson.GsonResponseBodyConverter.convert (GsonResponseBodyConverter.java:1)
retrofit2.OkHttpCall.a (OkHttpCall.java:59)
retrofit2.OkHttpCall.execute (OkHttpCall.java:73)
retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall.execute (DefaultCallAdapterFactory.java:2)
com.cn.managers.CNServiceManager.fetchChapters (CNServiceManager.java:2)
com.cn.tasks.FetchChaptersTask.doInBackground (FetchChaptersTask.java:2)
com.cn.tasks.FetchChaptersTask.doInBackground (FetchChaptersTask.java:2)
FetchChaptersTask类中的doInBackground方法如下
@Override
protected ArrayList<Chapter> doInBackground(Void... voids) {
return CNServiceManager.fetchChapters(subjectId, purpose);
}
在 CNServiceManager 中定义了方法 fetchChapters (subjectId, Purpose)。该方法基本上是使用 Retrofit2 和 GSON Converter 从 API 获取章节列表。 API调用如下。 CNServiceManager类如下:
public class CNServiceManager {
public static final String PREF_AUTHENTICATION_TOKEN = "CNServiceManager_authentication_token";
public static final String PREF_SESSION_ID = "CNServiceManager_session_id";
private interface CNService {
@GET("v2/chapters/{subjectId}/{purpose}")
Call<ArrayList<Chapter>> fetchChapters(@Header("Authentication-Token") String authentication,
@Path("subjectId") long subjectId,
@Path("purpose") String purpose);
}
/**
* Authorization token
*/
private static String mAuthorizationToken;
/**
* The main interface to server
*/
private static CNService mCNService;
/**
* Initialize
*
* @param context
*/
public static void init(Context context) {
OkHttpClient httpClient = new OkHttpClient.Builder()
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.0.105:8000/api/")
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build();
long applicationId = 9;
String applicationSecret = "AppSecret";
mAuthorizationToken = String.format(Locale.ENGLISH, "%d/%s", applicationId, applicationSecret);
mCNService = retrofit.create(CNService.class);
}
/**
* Returns authorization code
*
* @return
*/
private static String getAuthorizationToken() {
return mAuthorizationToken;
}
/**
* Returns authentication code
*
* @return
*/
private static String getAuthenticationToken() {
return PreferencesManager.getString(PREF_AUTHENTICATION_TOKEN, null);
}
/**
* Returns chapters
*
* @param subjectId
* @param purpose
* @return
*/
public static ArrayList<Chapter> fetchChapters(long subjectId, String purpose) {
try {
Call<ArrayList<Chapter>> call = mCNService.fetchChapters(getAuthenticationToken(), subjectId, purpose);
Response<ArrayList<Chapter>> response = call.execute();
return response.body();
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
最后,这是章节模型的编码方式。
public class Chapter {
/**
* Id of the chapter
*/
private long id;
/**
* Name of the chapter
*/
private String name;
/**
* Chapter
*
* @param id
* @param name
*/
public Chapter(long id, String name) {
this.id = id;
this.name = name;
}
/**
* Chapter
*/
public Chapter() {
this(0, null);
}
/**
* Returns the id of the chapter
*
* @return
*/
public long getId() {
return id;
}
/**
* Sets the id of the chapter
*
* @param id
*/
public void setId(long id) {
this.id = id;
}
/**
* Returns the name of the chapter
*
* @return
*/
public String getName() {
return name;
}
/**
* Sets the name of the chapter
*
* @param name
*/
public void setName(String name) {
this.name = name;
}
}
正如我在开头提到的,我在 Google Play 发布前报告和一些实时用户中收到了崩溃报告。但在我的设备和模拟器上,它没有崩溃。
最佳答案
请不要使用 AsyncTask 进行 Retrofit。相反,您可以使用 Reterofit 回调,如下所示。
public static void init(Context context) {
OkHttpClient httpClient = new OkHttpClient.Builder()
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.0.105:8000/api/")
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build();
long applicationId = 9;
String applicationSecret = "AppSecret";
mAuthorizationToken = String.format(Locale.ENGLISH, "%d/%s", applicationId, applicationSecret);
mCNService = retrofit.create(CNService.class);
// additional code instead of AsyncTask
Call<List<Chapter>> call = mCNService.fetchChapters();
call.enqueue(new Callback<List<Chapter>>() {
@Override
public void onResponse(Call<List<Chapter>> call, Response<List<Chapter>> response) {
progressDoalog.dismiss();
generateDataList(response.body());
}
@Override
public void onFailure(Call<List<Chapter>> call, Throwable t) {
progressDoalog.dismiss();
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
希望这能解决您的问题
关于java - 致命异常 : java. lang.RuntimeException - 由 java.lang.IllegalStateException 引起。应为 BEGIN_ARRAY,但实际为 BEGIN_OBJECT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61431552/