SettingsActivity
和一个我的volley
开展工作的课程。在我的网络服务中,它有很多数据需要转换为ArrayList
并保存到我的Database
;我有一个两个网络服务,在第一个完成之前调用,第二个开始之前它会延迟1秒。在Log
之后,它总是会显示以下内容
I/Choreographer: Skipped 226 frames! The application may be doing too much work on its main thread.
V/RenderScript: 0x5595d9d0e0 Launching thread(s), CPUs 8
W/art: Suspending all threads took: 20.500ms
W/SQLiteConnectionPool: A SQLiteConnection object for database '/data/data/com.app.myapp/databases/myDB.sqlite' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
I/art: Background partial concurrent mark sweep GC freed 38249(2025KB) AllocSpace objects, 2(968KB) LOS objects, 40% free, 16MB/26MB, paused 569us total 130.628ms
I/Choreographer: Skipped 1528 frames! The application may be doing too much work on its main thread.
我已经检查了我的数据库在使用后是否关闭,并且所有数据库都已关闭。但我仍然有database is leaked
消息和Skipped xxx frames
。我已经尝试创建一个新主题,我在SettingsActivity
调用我的class
时调用我的Volley
类似
btnSync.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
Thread thread = new Thread(new Runnable(){
@Override
public void run(){
Parameter.parameterOneVolley(SettingsActivity.this, getApplicationContext());
}
});
}
});
尝试此操作后,我遇到了Can't create handler inside thread that has not called Looper.prepare()
然后也尝试使用这个
runOnUiThread(new Runnable() {
@Override
public void run() {
Parameter.parameterOneVolley(SettingsActivity.this, getApplicationContext());
}
});
但是我收到了Skipped frames
消息。怎么解决?非常感谢您的帮助。
在我的Paramater
课程中,我也打电话给ProgressDialog
。
这是我Paramter.parameterOneVolley
public static void parameterOneVolley(final Activity activity, final Context context) {
final ProgressDialog pd = new ProgressDialog(activity);
pd.setMessage("Fetching data....");
pd.show();
initializeDatabase(context);
sqLiteAdapter = new SQLiteAdapter(activity);
regionList = new ArrayList<Region>();
divisionList = new ArrayList<Division>();
final Response.Listener<JSONObject> listener = new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray regionArr = response.getJSONArray("Region");
JSONArray divisionArr = response.getJSONArray("Division");
sqLiteAdapter.openToRead();
for(int i = 0; i < regionArr.length(); i++){
JSONObject regionObj = (JSONObject) regionArr.get(i);
Region region = new Region(regionObj.getInt("RegionId"),regionObj.getString("Region"));
regionList.add(region);
if(regionList.size()!=0) {
sqLiteAdapter.insertOrReplaceRegion(regionList);
}
}
for(int i = 0; i < divisionArr.length(); i++){
JSONObject divisionObj = (JSONObject) divisionArr.get(i);
Division division = new Division(divisionObj.getInt("RegionId"),divisionObj.getInt("DivisionId"),divisionObj.getString("Division"));
divisionList.add(division);
if(divisionList.size()!=0) { sqLiteAdapter.insertOrReplaceDivision(divisionList);
}
}
sqLiteAdapter.close();
if(pd != null && pd.isShowing()) {
pd.dismiss();
}
} catch (JSONException e) {
e.printStackTrace();
sqLiteAdapter.close();
if(pd != null && pd.isShowing()) {
pd.dismiss();
}
Toast.makeText(context,
e.getMessage(), Toast.LENGTH_SHORT).show();
}
Toast.makeText(context, "Successfully synced.", Toast.LENGTH_SHORT).show();
//call next web service
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
parameterTwoVolley(activity, context);
}
}, 1000);
}
};
final Response.ErrorListener errorListener = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if(pd != null && pd.isShowing()) {
pd.dismiss();
}
if (error.networkResponse != null) {
Log.d(TAG, "Error Response code: " + error.networkResponse.statusCode);
Toast.makeText(context, error.networkResponse.statusCode, Toast.LENGTH_SHORT).show();
}
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
Log.d(TAG, "Error Response code: Timeout/NoConnection");
Toast.makeText(context, "Timeout/NoConnection", Toast.LENGTH_SHORT).show();
} else if (error instanceof AuthFailureError) {
Log.d(TAG, "Error Response code: AuthFailureError");
Toast.makeText(context, "AuthFailureError", Toast.LENGTH_SHORT).show();
} else if (error instanceof ServerError) {
Log.d(TAG, "Error Response code: ServerError");
Toast.makeText(context, "ServerError", Toast.LENGTH_SHORT).show();
} else if (error instanceof NetworkError) {
Log.d(TAG, "Error Response code: NetworkError");
Toast.makeText(context, "NetworkError", Toast.LENGTH_SHORT).show();
} else if (error instanceof ParseError) {
Log.d(TAG, "Error Response code: ParseError");
Toast.makeText(context, "ParseError", Toast.LENGTH_SHORT).show();
}
if(pd != null && pd.isShowing()) {
pd.dismiss();
}
}
};
}
我尝试添加
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
pd = new ProgressDialog(activity);
pd.setMessage("Fetching data....");
pd.show();
}
}
});
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if(pd != null && pd.isShowing()) {
pd.dismiss();
}
Toast.makeText(context, "Successfully synced.", Toast.LENGTH_SHORT).show();
}
});
每次我使用Progress Dialog and Toast
但我仍然遇到Skipped frames
还尝试使用ProgressBar
来显示和隐藏它,但仍遇到skipped frames
答案 0 :(得分:1)
在Android中,只有主线程(也称为UI线程)可以更新视图。这是因为在Android中UI工具包不是线程安全的。
当您尝试从工作线程更新UI时,Android会抛出此异常。如果要从另一个Thread更新UI,请使用Handler。
final Handler handler=new Handler();
new Thread(new Runnable() {
@Override
public void run() {
//your code
handler.post(new Runnable() {
@Override
public void run() {
Parameter.parameterOneVolley(SettingsActivity.this, getApplicationContext());
}
});
}
}).start();