gpt4 book ai didi

java - 如何避免应用程序可能在其主线程上做太多工作

转载 作者:行者123 更新时间:2023-12-02 12:24:18 25 4
gpt4 key购买 nike

我有两个类。一个是我的 SettingsActivity 和一个由我的 volley 完成工作的类。在我的网络服务中,它有大量数据需要转换为 ArrayList 并将其保存到我的数据库中;我有两个 Web 服务要在第一个服务完成后调用,第二个服务启动之前会延迟 1 秒。在这些事情之后,它在我的日志中总是显示以下内容

 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.

我已经检查我的数据库在使用后是否关闭,并且所有数据库都已关闭。但我仍然收到数据库泄露消息和跳过了xxx帧。我已经尝试创建一个新线程,在为我的 Volley 调用 class 时,在我的 SettingsActivity 中调用我的类,例如

   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());
}
});
}
});

尝试此操作后,我遇到无法在未调用 Looper.prepare() 的线程内创建处理程序

然后也尝试使用这个

 runOnUiThread(new Runnable() {

@Override
public void run() {
Parameter.parameterOneVolley(SettingsActivity.this, getApplicationContext());
}
});

但是我收到一条消息跳过帧。怎么解决呢?预先非常感谢您的帮助。

在我的 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();
}
});

每次我使用进度对话框和Toast,但我仍然遇到跳过帧

还尝试使用 ProgressBar 来代替并显示和隐藏它,但仍然遇到跳帧

最佳答案

在 Android 中,只有主线程(也称为 UI 线程)可以更新 View 。这是因为在 Android 中,UI 工具包不是线程安全的。

当您尝试从工作线程更新 UI 时,Android 会抛出此异常。如果您想从另一个线程更新 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();

关于java - 如何避免应用程序可能在其主线程上做太多工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45559442/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com