안드로이드 Fragment가 초기 호출시 느린 이유가 궁금합니다.. [ 재질문 ]

조회수 626회


public class a {

   private static int[] idLayoutMenuButtonNumber = {
            R.id.idButton_a,
            R.id.idButton_b,
            R.id.idButton_c,
            R.id.idButton_d,
            R.id.idButton_e,
    };
    public static Button[] idLayoutMenuButton = new Button[idLayoutMenuButtonNumber.length];

    public static   Menu_a            menu_a;
    public static   Menu_b             menu_b;
    public static   Menu_c              menu_c;
    public static   Menu_d             menu_d;
    public static   Menu_f           menu_f;

    public static Menu_Base menuSystemInstances[] = null;


    int selectedMainMenuIndex,

    final static int MAIN_MENU_NONE             = -1;
    final static int MAIN_MENU_a          = 0;
    final static int MAIN_MENU_b           = 1;
    final static int MAIN_MENU_c            = 2;
    final static int MAIN_MENU_d           = 3;
    final static int MAIN_MENU_e         = 4;
    final static int MAIN_MENU_f         = 5;   

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        MenuButtonDefine(idLayoutMenuButton, idLayoutMenuButtonNumber);

        menu_a            =       new Menu_a();
        menu_b             =       new Menu_b();
        menu_c              =       new Menu_c();
        menu_d             =       new Menu_d();
        menu_e           =       new Menu_e();
        menu_f         =       new Menu_f();


        menuSystemInstances = new Menu_Base[] {
                menu_a,
                menu_b,
                menu_c,
                menu_d,
                menu_e,
                menu_f,
        };

        SYSTEM_NENU_MAIN_NUM = menuSystemInstances.length;
        selectedMainMenuIndex = MAIN_MENU_NONE;

    }

     public void MenuButtonDefine(final Button[] idLayoutMenuButton, int[] idLayoutMenuButtonNumber) {
        idImageButton_Exit = findViewById(R.id.idImageButton_Exit);
        idImageButton_Exit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                _Adpater_Menu.setVisibility(View.GONE);
                selectedMainMenuIndex = MAIN_MENU_NONE;
            }
        });

        for(int i = 0 ; i < idLayoutMenuButton.length ; i++ ) {
            idLayoutMenuButton[i] = findViewById(idLayoutMenuButtonNumber[i]);
            idLayoutMenuButton[i].setOnClickListener(this);
            idLayoutMenuButton[i].setOnTouchListener(this);
        }
    }

public void selectSubMenu(int index){
        String subMenuTitleName[] = { "a", "b", "c", "d", "e", "f" };

        idLayoutMenuButton[selectedMainMenuCursor].setSelected(false);
        selectedMainMenuCursor = index;
        idLayoutMenuButton[selectedMainMenuCursor].setSelected(true);

        selectedMainMenuIndex = index;

        idLayoutTOP_TITLEName.setText(subMenuTitleName[selectedMainMenuIndex]);

        idLayoutMenuButton[saveMenuPosition].setBackgroundColor(Color.TRANSPARENT);
        idLayoutMenuButton[saveMenuPosition].setTextColor(Color.WHITE);

        switch(selectedMainMenuIndex){
            case MAIN_MENU_a          :
                saveMenuPosition = MAIN_MENU_a;
                getFragmentManager().beginTransaction().replace(R.id.idLayoutCNETER_SettingName, menu_a).addToBackStack(null).commit(); break;
            case MAIN_MENU_b           :
                saveMenuPosition = MAIN_MENU_b;
                getFragmentManager().beginTransaction().replace(R.id.idLayoutCNETER_SettingName, menu_b).addToBackStack(null).commit(); break;
            case MAIN_MENU_c            :
                saveMenuPosition = MAIN_MENU_c;
                getFragmentManager().beginTransaction().replace(R.id.idLayoutCNETER_SettingName, menu_c).addToBackStack(null).commit(); break;
            case MAIN_MENU_d           :
                saveMenuPosition = MAIN_MENU_d;
                getFragmentManager().beginTransaction().replace(R.id.idLayoutCNETER_SettingName, menu_d).addToBackStack(null).commit(); break;
            case MAIN_MENU_e         :
                saveMenuPosition = MAIN_MENU_e;
                getFragmentManager().beginTransaction().replace(R.id.idLayoutCNETER_SettingName, menu_e).addToBackStack(null).commit(); break;
            case MAIN_MENU_f       :
                saveMenuPosition = MAIN_MENU_f;
                getFragmentManager().beginTransaction().replace(R.id.idLayoutCNETER_SettingName, menu_f).addToBackStack(null).commit(); break;
        }
    }
}

현재 Fragment를 호출하는 코드는 위와 같습니다. 정확히는 저런 형식입니다.

호출 방법이 제대로 적혀있지 않은데 현재 보여드리는 코드에서는 6개 정도의 버튼이 있지만 실제로는 18개 정도 버튼이 있고 각각 다른 플래그먼트를 연결해줍니다.

하드키 중 하나를 누르면 메뉴 화면이 GONE에서 VIS 처리 되고, 그 이후 그 안에 버튼들을 이용하여 각각의 Fragment를 호출합니다.

저번에 질문했을 때, 어느 유저분이 알려주신데로 메인상에 무거운 쓰레드가 돌고있는지를 보라고 하셨는데, 좀 어려운 작업의 쓰레드가 돌고있긴하지만 그렇게 까지 심한 건 아니기에 그 문제는 아니라고 생각합니다.

첫번째 호출에서만 딜레이가 걸리는 문제, 동일한 항목을 두번째 호출할 때는 딜레이가 전혀 없습니다만, 서로 다른 항목을 제일 처음 호출 했을 때는 딜레이가 심합니다..

  • (•́ ✖ •̀)
    알 수 없는 사용자
  • 해당 이슈 같은 경우에는 fragment 코드 기준으로만 문제점을 분석 할 수 없습니다. fragment transaction 이 어떤형태인지도 봐야하고 전반적인 구조가 어떤 형태인지 분석해볼 필요가 있습니다. 초기 UI element 를 초기화 되는 시점에는 돌아가는 task 에 따라 얼마든지 프레임 저하가 발생 할 수 있습니다. 알 수 없는 사용자 2019.10.16 14:51
  • 프레임 저하가 발생하는 구간을 확인할 수 있는 방법은 없을까요? 알 수 없는 사용자 2019.10.16 15:24
  • 어플을 실행시킨다음에 IDE 하단에 Profiler 탭에서 cpu, 메모리 사용량등을 확인할 수 있을겁니다. 거기서 그래프가 널뛰나 확인해보세요 김은기 2019.10.17 09:43
  • 그건 확인을 해봣는데, cpu 메모리 전부 안정적으로 유지됩니다. CPU 점유율은 항상 40 ~ 50프로 정도고, 플래그먼트를 부르는 순간에만 한 55~57,8 정도 올라가는 현상이 보이기는 합니다만.. 메모리는 128 기준으로 기본 85~95 정도고 플래그먼트를 부르는 순간만 100 정도까지 올라가네요 알 수 없는 사용자 2019.10.17 09:58
  • getSupportFragmentManager() 대신에 getFragmentManager() 를 쓰는 이유가 있습니까? 김은기 2019.10.17 10:06
  • 프래그먼트인 Menu_a~f 클래스가 전부 다른 클래스인데 거기서 onResume 까지 초기화 되는게 어떤게 있습니까? 김은기 2019.10.17 10:11
  • 현재 Framgent 가 support.v4 Fragment가 아니라서... 라고 하는게 맞을런지 모르게쎈요 알 수 없는 사용자 2019.10.17 10:12
  • 그러면 그냥 getFragmentManager() 를 쓰는게 맞을것같네요. 김은기 2019.10.17 10:18
  • onResume 까지 초기화 되는게 어떤게 있습니까? 라는 질문은 무슨 말씀이신지... ㅠ 알 수 없는 사용자 2019.10.17 10:31
  • 답변에 다시 질문드렸습니다 김은기 2019.10.17 10:34

1 답변

  • 의심할 수 있는 부분은 2가지라고 생각됩니다.

    좀 어려운 작업의 쓰레드가 돌고있긴하지만 그렇게 까지 심한 건 아니기에 그 문제는 아니라고 생각합니다.

    저희가 cpu 가 아니기 때문에 판단할 수 없는 문제입니다.

    commit()을 호출하더라도 즉시 트랜잭션이 실행되지는 않습니다. 그보다는 스레드가 준비되는 즉시 최대한 빨리 액티비티의 UI 스레드("기본" 스레드)에서 이 트랜잭션이 수행되도록 일정을 예약하는 것에 가깝습니다. 하지만 필요한 경우 UI 스레드에서 executePendingTransactions()를 호출하면 commit()이 제출한 트랜잭션을 즉시 실행할 수 있습니다. 트랜잭션이 다른 스레드의 작업에 대한 종속성이 아니라면 굳이 이렇게 해야 할 필요는 없습니다.

    공식 문서 가이드에 안내되는 부분입니다. 위 메서드를 사용해서 실행해보세요.

    두번째는 프래그먼트 자체가 onCreate 부터 onResume 까지 초기화 작업이 많이 걸린다는것입니다. 해당 부분을 가져와서 질문을 업데이트 해주시면 좋겠습니다.

    • 혹시 1:1로 얘기드릴 수 있는 방법이 있을까요? 코드를 전부 보여드리는게 빠르지 않을까 싶은데.. 알 수 없는 사용자 2019.10.17 10:59
    • 애매한 부분이 좀 많아서.. 알 수 없는 사용자 2019.10.17 10:59
    • 네 점심 끝나고 연락드리겠습니다, 알 수 없는 사용자 2019.10.17 12:00
    • 김은기 님께서 좋은 답변 주신것 같습니다 추가적으로 앱 실행 시점의 로그캣 상에서 "skiped xx frames!!" 로그가 발생하는지도 살펴보세요. 알 수 없는 사용자 2019.10.17 18:55
    • pistolcaffe 님 결국 모든 방법을 사용해도 해결을 보지 못했습니다... 알 수 없는 사용자 2019.10.17 20:04
    • 추가로 그런 에러는 뜨지 않습니다 알 수 없는 사용자 2019.10.17 20:05

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)