简体   繁体   English

Choreographer:跳帧:应用程序可能在其主线程上做了太多工作

[英]Choreographer: Skipped frames : The application may be doing too much work on its main thread

In my android application I am getting "The application may be doing too much work on its main thread" as warning and api call taking to much time to make response.I showed it with an example.I have a radio button with 2 cases each will make an api call on click and result will show a list of data to users.Below is my code.在我的 android 应用程序中,我收到“应用程序可能在其主线程上做太多工作”作为警告,api 调用需要很长时间才能做出响应。我用一个例子展示了它。我有一个单选按钮,每个按钮有 2 个案例将在单击时进行 api 调用,结果将向用户显示数据列表。以下是我的代码。

protected void onCreate(Bundle savedInstanceState) {
    /**   Other code **/
    rdbGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
            pos = radioGroup.indexOfChild(findViewById(checkedId));
            switch (pos) {
                case 0:
                    if (screenType == 1) {
                        getClassTeacherList();
                    } else {
                        rcyTeachers.setVisibility(View.GONE);
                    }
                    fabAddClassTeacher.setTitle("Add class teacher");
                    return;
                case 2:
                    if (screenType == 1) {
                        getAcademicTeachersList();
                    } else {
                        rcyTeachers.setVisibility(View.GONE);
                    }
                    fabAddClassTeacher.setTitle("Add Teacher");
                    return;
                default:
            }
        }
    });

private void getClassTeacherList() {
    academicPeriod = (AcademicPeriod) mSpnPeriod.getItemAtPosition(keyPos);
    if (isServerReachable(getApplicationContext())) {
        classTeacherList = serverAuthenticateService.getClassTeacherList(selClass.getId(),academicPeriod.getId(), authtoken, getApplicationContext());
        if (AppBackupCache.checkToken == 200) {
            showClassTeacherList();
        } else if (AppBackupCache.checkToken == 401) {
            manager.invalidateAuthToken("com.lss.loop", authtoken);
            authtoken = null;
            final AccountManagerFuture<Bundle> future = manager.getAuthToken(mAccount, AccountGeneral.AUTHTOKEN_TYPE_FULL_ACCESS, new Bundle(), true, null, null);
            new Thread(new Runnable() {
                public void run() {
                    try {
                        Bundle bnd = (Bundle) future.getResult();
                        authtoken = bnd.getString("authtoken");
                        if (authtoken != null) {
                            classTeacherList = serverAuthenticateService.getClassTeacherList(selClass.getId(),academicPeriod.getId(), authtoken, getApplicationContext());
                            if (AppBackupCache.checkToken == 200) {
                                showClassTeacherList();
                                return;
                            } else {
                                getMsgBox("Error", "Something went wrong");
                                return;
                            }
                        }

                        getMsgBox("", "Token not refreshed....");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        AppBackupCache.checkToken = 401;
        return;
    }
    getMsgBox("No connection", "No connection");
}

public boolean isServerReachable(Context applicationContext) {
    ConnectivityManager connMan = (ConnectivityManager) applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = connMan.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnected()) {
        try {
            URL urlServer = new URL(strUrl);
            HttpURLConnection urlConn = (HttpURLConnection) urlServer.openConnection();
            urlConn.setConnectTimeout(3000); //<- 3Seconds Timeout
            urlConn.connect();
            return urlConn.getResponseCode() == 200;
        } catch (MalformedURLException e1) {
            return false;
        } catch (IOException e) {
            return false;
        }
    }
    return false;
    //return true;
}


private void showClassTeacherList() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (classTeacherList.size() > 0) {
                rcyTeachers.setVisibility(View.VISIBLE);
                linLayColor1.setVisibility(View.VISIBLE);
                linLaySub.setVisibility(View.GONE);
                classTeacherGridAdapter = new ClassTeacherGridAdapter(ClassTeacherActivity.this, classTeacherList, fontFamily, screenType, 1);
                rcyTeachers.setAdapter(classTeacherGridAdapter);
                ViewCompat.setNestedScrollingEnabled(rcyTeachers, true);
                return;
            }
            rcyTeachers.setVisibility(View.GONE);
            linLayColor1.setVisibility(View.GONE);
        }
    });
}

ServerAuthenticateService.java: ServerAuthenticateService.java:

@Override
public List<ClassTeacher> getClassTeacherList(int classId, int academicId, String authtoken, Context applicationContext) {
    HttpHeaders headers = new HttpHeaders();
    headers.set("Authorization", "bearer " + authtoken);
    MultiValueMap<String, String> map = new LinkedMultiValueMap();
    map.add("classId", String.valueOf(classId));
    map.add("academicId", String.valueOf(academicId));
    ResponseEntity<String> restRes = this.restTemplate.exchange(apiUrl + "/getClassTeacherList", HttpMethod.POST, new HttpEntity(map, headers), String.class, new Object[0]);
    if (restRes.getStatusCode() == HttpStatus.OK) {
        AppBackupCache.checkToken = ItemTouchHelper.Callback.DEFAULT_DRAG_ANIMATION_DURATION;
        String resBody = (String) restRes.getBody();
        Type listType = new TypeToken<List<ClassTeacher>>() {}.getType();
        List<ClassTeacher> allActPgmMap = (List) this.gson.fromJson(resBody, listType);
        return allActPgmMap;
    } else if (restRes.getStatusCode() == HttpStatus.UNAUTHORIZED) {
        AppBackupCache.checkToken = 401;
        return null;
    } else {
        AppBackupCache.checkToken = 402;
        return null;
    }
}

Below is the warming i am getting.下面是我得到的变暖。

I/Choreographer: Skipped 687 frames!  The application may be doing too much work on its main thread.
I/OpenGLRenderer: Davey! duration=11662ms; Flags=0, IntendedVsync=1315104621338, Vsync=1326554620880, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=1326567046366, AnimationStart=1326567174126, PerformTraversalsStart=1326567180324, DrawStart=1326747726176, SyncQueued=1326760565187, SyncStart=1326761318573, IssueDrawCommandsStart=1326761742323, SwapBuffers=1326766654823, FrameCompleted=1326767746542, DequeueBufferDuration=298000, QueueBufferDuration=332000, 

 I/Choreographer: Skipped 682 frames!  The application may be doing too much work on its main thread.
 I/OpenGLRenderer: Davey! duration=11418ms; Flags=0, IntendedVsync=1354296057548, Vsync=1365662723760, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=1365665791303, AnimationStart=1365665859063, PerformTraversalsStart=1365665871094, DrawStart=1365707384015, SyncQueued=1365711047505, SyncStart=1365711676880, IssueDrawCommandsStart=1365712054224, SwapBuffers=1365714258860, FrameCompleted=1365715220318, DequeueBufferDuration=243000, QueueBufferDuration=341000, 

In my application, I have lots of API calls and most of the time I am getting this warning, what should I do to avoid this and make my request and application work faster?在我的应用程序中,我有很多 API 调用,并且大多数时候我都会收到此警告,我应该怎么做才能避免这种情况并使我的请求和应用程序运行得更快?

If I'm not mistaken, at least once your ServerAuthenticateService 's getClassTeacherList method is called on the main (UI) thread when the onCheckedChange callback is invoked.如果我没记错的话,至少在调用onCheckedChange回调时在主(UI)线程上调用ServerAuthenticateServicegetClassTeacherList方法。 You should instead move the web API call to another thread, so that the main thread isn't "frozen" waiting for the result of the web API call. You should instead move the web API call to another thread, so that the main thread isn't "frozen" waiting for the result of the web API call.

From https://developer.android.com/guide/components/processes-and-threads :https://developer.android.com/guide/components/processes-and-threads

... if everything is happening in the UI thread, performing long operations such as network access or database queries will block the whole UI. ...如果一切都发生在 UI 线程中,执行长时间操作(例如网络访问或数据库查询)将阻塞整个 UI。 When the thread is blocked, no events can be dispatched, including drawing events.当线程被阻塞时,不能调度任何事件,包括绘图事件。 From the user's perspective, the application appears to hang.从用户的角度来看,应用程序似乎挂起。 Even worse, if the UI thread is blocked for more than a few seconds (about 5 seconds currently) the user is presented with the infamous "application not responding" (ANR) dialog.更糟糕的是,如果 UI 线程被阻塞超过几秒(目前大约 5 秒),用户会看到臭名昭著的“应用程序无响应”(ANR)对话框。 The user might then decide to quit your application and uninstall it if they are unhappy.如果他们不满意,用户可能会决定退出您的应用程序并卸载它。

EDIT: also the isServerReachable method shouldn't be invoked on the main thread.编辑:也不应该在主线程上调用isServerReachable方法。

EDIT2: You can try this way, although I don't know all the implications of your code being called on another thread: EDIT2:您可以尝试这种方式,尽管我不知道在另一个线程上调用您的代码的所有含义:

private void getClassTeacherList() {
academicPeriod = (AcademicPeriod) mSpnPeriod.getItemAtPosition(keyPos);
new Thread(new Runnable() {
            public void run() {
if (isServerReachable(getApplicationContext())) {
    classTeacherList = serverAuthenticateService.getClassTeacherList(selClass.getId(),academicPeriod.getId(), authtoken, getApplicationContext());
    if (AppBackupCache.checkToken == 200) {
        showClassTeacherList();
    } else if (AppBackupCache.checkToken == 401) {
        manager.invalidateAuthToken("com.lss.loop", authtoken);
        authtoken = null;
        final AccountManagerFuture<Bundle> future = manager.getAuthToken(mAccount, AccountGeneral.AUTHTOKEN_TYPE_FULL_ACCESS, new Bundle(), true, null, null);
        

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 编舞:跳过33帧! 该应用程序可能在其主线程上做过多的工作 - Choreographer: Skipped 33 frames! The application may be doing too much work on its main thread I / Choreographer(12759):跳过了40帧! 该应用程序可能在其主线程上做过多的工作 - I/Choreographer(12759): Skipped 40 frames! The application may be doing too much work on its main thread 编舞:跳过53帧! 该应用程序可能在其主线程上做过多的工作 - Choreographer: Skipped 53 frames! The application may be doing too much work on its main thread I /编舞:跳过33帧! 应用程序可能在其主线程上做太多工作? - I/Choreographer: Skipped 33 frames! The application may be doing too much work on its main thread? 编舞:跳过127帧! 该应用程序可能在其主线程上做过多的工作 - Choreographer: Skipped 127 frames! The application may be doing too much work on its main thread I/编舞:跳过439帧! 应用程序可能在其主线程上做了太多工作 - I/Choreographer: Skipped 439 frames! The application may be doing too much work on its main thread 跳过32帧! 该应用程序可能会在其主线程上执行过多的工作,然后执行FATAL EXCEPTION:main - Skipped 32 frames! The application may be doing too much work on its main thread and then FATAL EXCEPTION: main 跳过60帧! 应用程序可能在其主线程上做了太多工作 - Skipped 60 frames! The application may be doing too much work on its main thread Android Map-跳帧! 该应用程序可能在其主线程上做过多的工作 - Android Map - Skipped frames! The application may be doing too much work on its main thread Phonegap-跳过33帧!应用程序可能在其主线程上做了太多工作 - Phonegap-Skipped 33 frames! The application may be doing too much work on its main thread
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM