在导航抽屉内部管理片段中的线程(用于平滑动画)

时间:2017-02-23 08:55:27

标签: java android multithreading android-studio threadpool

我想问你是否有人遇到和我一样的问题。

I/art: Do partial code cache collection, code=250KB, data=130KB
I/art: After code cache collection, code=248KB, data=129KB
I/art: Increasing code cache capacity to 1024KB
I/Choreographer: Skipped 143 frames!  The application may be doing too much work on its main thread.

我的Android应用程序的设计很简单,我的目标网页中有一个导航抽屉,然后我在每个抽屉项目中都有多个碎片 ...所以这意味着我只在我正在使用NavDrawer的登陆页面上使用活动。

当我尝试在每个片段上添加日历,回收站视图等公共存储库时,我收到上述错误。

我在线阅读了一些文章和示例,发现我应该使用 AsyncTask<> runOnUIThread 并运行操作主线程/ UI线程。虽然我试图在我的Fragment上应用那些线程同样的错误。

但是操作并不是很重,我只是加载了日历库并在我的片段中的onCreateView上实例化它们......

我希望你能给我一些建议或最佳实践来管理这种情况......我知道有人遇到了同样的问题。呵呵。提前谢谢。

I tried this link, but it is more likely another scenario

根据CODES要求:

public class CalendarFragment extends Fragment implements
        RobotoCalendarView.RobotoCalendarListener,
        CalendarListAdapter.OnItemClickListener
        // CalendarListAdapter.CallbackInterface // Should Implemented on the Main thread/Activity if used as fragment
{

    private RobotoCalendarView robotoCalendarView;
    private Context context;

    private CalendarListAdapter mListAdapter;
    private RecyclerView mSearchResultsList;
    private static final int REQUEST_CODE = 1234;

    private List<ServiceJobWrapper> results = null;


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = /*(View)*/ inflater.inflate(
                R.layout.calendar_activity, container, false);
        setContext(container.getContext());

        /**NOTE FROM HERE**/
        setUpCalendarView(view);
//        UICalendarLibTask mCalendarTask = new UICalendarLibTask(view);
//        mCalendarTask.execute((Void) null);

       /* setUpRecyclerView(view);
        setupResultsList(view);
        if (results == null) {
            //final View view = v;
            *//*new Thread(new Runnable() {
                public void run() {
                    populateCardList();
                }
            }).start();*//*
            UITask mAuthTask = new UITask();
            mAuthTask.execute((Void) null);
            // populateCardList();

        }*/
        return view;
    }

    /*@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d("CalendarFragment:",  "I'm on the onCreate");
    }*/
    /**
     * These Two Lines should be included on every Fragment to maintain the state and donnot load again
     *
     * @param outState
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        setRetainInstance(true);
        Log.d("CalendarFragment: ", "I'm on the onSaveInstanceState");
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (results == null) { // If Data is Null then fetch the Data List again
//            UpdateJobServiceTask task = new UpdateJobServiceTask(this.getView());
//            task.execute("");
            //populateCardList();
        } else { // Restore the Data List again
            mListAdapter.swapData(results);
        }
        Log.d("CalendarFragment: ", "I'm on the onActivityCreated");
    }

    private void setContext(Context c) {
        this.context = c;
    }

    public void setUpRecyclerView(View upRecyclerView) {
        mSearchResultsList = (RecyclerView) upRecyclerView.findViewById(R.id.calendar_service_job_list);
    }

    public void setupResultsList(View view) {
        mListAdapter = new CalendarListAdapter(view.getContext());
        mSearchResultsList.setAdapter(mListAdapter);
        mSearchResultsList.setLayoutManager(new LinearLayoutManager(view.getContext()));
    }

    /**
     * Set up the Calendar View Listener on Click of the Date/Month
     *
     * @param view
     */
    private void setUpCalendarView(View view) {
        // Gets the calendar from the view
        robotoCalendarView = (RobotoCalendarView) view.findViewById(R.id.robotoCalendarPicker);
        Button markDayButton = (Button) view.findViewById(R.id.markDayButton);
        markDayButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Calendar calendar = Calendar.getInstance();
                Random random = new Random(System.currentTimeMillis());
                int style = random.nextInt(2);
                int daySelected = random.nextInt(calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                calendar.set(Calendar.DAY_OF_MONTH, daySelected);

                switch (style) {
                    case 0:
                        robotoCalendarView.markCircleImage1(calendar);
                        break;
                    case 1:
                        robotoCalendarView.markCircleImage2(calendar);
                        break;
                    default:
                        break;
                }
            }
        });

        // Set listener, in this case, the same activity
        robotoCalendarView.setRobotoCalendarListener(this);

        robotoCalendarView.setShortWeekDays(false);

        robotoCalendarView.showDateTitle(true);

         robotoCalendarView.updateView();
    }

//    @Override
//    protected void attachBaseContext(Context newBase) {
//        super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
//    }

    /*@Override
    public void onAttach(Context context) {
        super.onAttach(context);
        //super.onAttach(CalligraphyContextWrapper.wrap(context));
    }*/

    @Override
    public void onDayClick(Calendar daySelectedCalendar) {
        Log.d("onDayClick: ", daySelectedCalendar.getTime() + "");
    }

    @Override
    public void onDayLongClick(Calendar daySelectedCalendar) {
        Log.d("onDayLongClick: ", daySelectedCalendar.getTime() + "");
    }

    @Override
    public void onRightButtonClick() { Log.d("onRightButtonClick!", "Calendar"); }

    @Override
    public void onLeftButtonClick() {
        Log.d("onLeftButtonClick!", "Calendar");
        // Toast.makeText(this.context, "onLeftButtonClick!", Toast.LENGTH_SHORT).show();
    }

    private void activityResultIntent() {
        Intent check = new Intent();
        startActivityForResult(check, REQUEST_CODE);
    }

    /**
     * Setting up for the Result OnClick inside the CardView on the List Adapter
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (resultCode) {

            case RESULT_OK:

                /*if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                    System.out.println("I'm in onActivityResult");
                    _speaker = new Speaker(getApplicationContext());
                    ImageButton buttonSpeakKoreanAlphabet = (ImageButton) findViewById(R.id.buttonSpeakKorean_alphabet);
                    buttonSpeakKoreanAlphabet.setClickable(true);
                } else {
                    Intent install = new Intent();
                    install.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                    startActivity(install);
                }*/

                break;

            case RESULT_CANCELED:
                // ... Handle this situation
                break;
            default:
                break;
        }
    }

    private void populateCardList() {
        // Data to be Fetch to the CardView
        // List<ServiceJobWrapper> results = null;//getAllData(this.getContext());
        /*new UIThreadHandler(getContext()).runOnUiThread(new Runnable() {
            @Override
            public void run() {

            }
        });*/
        results = getAllDetailsOfLetters();
        mSearchResultsList.setHasFixedSize(true);
        mSearchResultsList.setLayoutManager(new LinearLayoutManager(context));
        mSearchResultsList.setItemAnimator(new DefaultItemAnimator());
        mListAdapter.swapData(results);

    }

    private class UpdateJobServiceTask extends AsyncTask<String, Void, String> {

        private View mView;

        public UpdateJobServiceTask(View view) {
            mView = view;
        }

        @Override
        protected String doInBackground(String... params) {
            populateCardList();

            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            //textView.setText(result);
        }
    }

    /***********************************
     * TEST                            *
     ***********************************/

    // Getting Details Data of all ALPHABET
    public List<ServiceJobWrapper> getAllDetailsOfLetters() {
        ArrayList<ServiceJobWrapper> translationList = new ArrayList<>();
        int x = 0;
        do {
            ServiceJobWrapper alpha = new ServiceJobWrapper();
            alpha.setID(Integer.parseInt(x + ""));
            alpha.setDay(x + "");
            alpha.setDate("TestDate" + x);
            alpha.setServiceNumber("00" + x);
            alpha.setCustomer("Customer" + x);
            alpha.setEngineer("Engineer" + x);
            alpha.setStatus((x % 2 == 1) ? "Pending" : "Completed");
            translationList.add(alpha);
            x++;
        } while (x != 10);

        return translationList;
    }


    @Override
    public void onClick(ServiceJobWrapper colorWrapper) {

    }

    /**
     * Represents an asynchronous Task
     * UITask mAuthTask = new UITask();
     mAuthTask.execute((Void) null);
     */
    public class UITask extends AsyncTask<Void, Void, Boolean> {
        UITask() {
        }

        @Override
        protected Boolean doInBackground(Void... params) {
            // TODO: attempt authentication against a network service.

            /*try {
                // Simulate network access.
                Thread.sleep(2000);
                // init_DrawerNav();
                //populateCardList();
            } catch (InterruptedException e) {
                return false;
            }*/

            results = getAllDetailsOfLetters();
            // TODO: register the new account here.
            return true;
        }

        @Override
        protected void onPostExecute(final Boolean success) {
            mSearchResultsList.setHasFixedSize(true);
            mSearchResultsList.setLayoutManager(new LinearLayoutManager(context));
            mSearchResultsList.setItemAnimator(new DefaultItemAnimator());
            mListAdapter.swapData(results);
        }

        @Override
        protected void onCancelled() {
        }
    }

    public class UICalendarLibTask extends AsyncTask<Void, Void, Boolean> {
        private View view;
        UICalendarLibTask(View v) {
            this.view = v;
        }

        @Override
        protected Boolean doInBackground(Void... params) {

            return true;
        }

        @Override
        protected void onPostExecute(final Boolean success) {
            setUpCalendarView(view);
        }

        @Override
        protected void onCancelled() {
        }
    }

}

在onCreateView上调用此结果:

setUpCalendarView(view); // First try without asynTask
// Second try with asynTask
//        UICalendarLibTask mCalendarTask = new UICalendarLibTask(view);
//        mCalendarTask.execute((Void) null);

这是片段的XML布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20sp"
android:background="@drawable/background">


<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/frameLayoutCalendar">

    <com.marcohc.robotocalendar.RobotoCalendarView
        android:id="@+id/robotoCalendarPicker"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</FrameLayout>

<FrameLayout
    android:layout_width="match_parent"
    android:id="@+id/frameLayoutButton"
    android:layout_height="wrap_content">

    <Button
        android:text="TEST RANDOM"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/markDayButton" />
</FrameLayout>

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:isScrollContainer="true"
    android:id="@+id/frameLayoutListOfServices">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/calendar_service_job_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:clipToPadding="false"
        android:paddingTop="60dp" />
</FrameLayout>

好吧,我没有看到我的帖子有任何错误,特别是在填充cardview时,但是当我尝试在同一片段上渲染recyclelerView和Calendar时,我得到上面的错误

注意: 我正在使用github的这个repo作为日历视图 RobotoCalendar Github

1 个答案:

答案 0 :(得分:0)

我不明白我的解决方案背后的秘密,但这解决了我的问题......

<强> BEFORE

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="20sp"
    android:background="@drawable/background">

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/frameLayoutCalendar">

<com.marcohc.robotocalendar.RobotoCalendarView
    android:id="@+id/robotoCalendarPicker"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

AFTER (我刚删除了行android:background="@drawable/background"

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20sp">

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
android:id="@+id/frameLayoutCalendar">

<com.marcohc.robotocalendar.RobotoCalendarView
    android:id="@+id/robotoCalendarPicker"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

有人会向我解释这个场景...... 我真的不需要设置我的布局背景,为了没有这个Choreagrapher错误,谢谢!

我希望有人也能帮到你,