为什么我的Android主屏幕小部件变慢?

时间:2019-09-02 14:39:56

标签: android performance android-widget android-adapterview

我已经开发了一些显示adapterviewflipper布局的主屏幕小部件。它们自动启动并具有3秒的翻转间隔。他们显示一个带有自定义动画进出动画的小集合(总时间为2秒)。收集数据每分钟刷新一次。

经过一段不确定的时间后,翻转间隔变得越来越大,可能需要花费约17秒的时间进行动画处理。我不明白为什么。

有android限制吗?内存泄漏问题? 如果我重新启动手机,则可以节省时间,但是不久之后我会遇到问题。

小部件布局

<AdapterViewFlipper
        android:id="@+id/calendar_widget_adapterViewFlipper"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:autoStart="true"
        android:flipInterval="3000"
        android:animateLayoutChanges="true"
        android:inAnimation="@animator/slide_in_bottom"
        android:outAnimation="@animator/fade_out"
        />

AppWidget Provider

 @Override
    public void onReceive(Context context, Intent intent) {

        //Log.d(LOG_TAG, "Received intent " + intent);

        switch (intent.getAction()){
            case ACTION_MESSAGE_DATA_UPDATE :

                ComponentName thisAppWidget = new ComponentName(context.getPackageName(), getClass().getName());
                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
                for (int appWidgetID: ids) {
                    appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetID, R.id.calendar_widget_adapterViewFlipper);
                }

                break;
...

App Widget Provider配置文件

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialKeyguardLayout="@layout/calendar_widget"
    android:initialLayout="@layout/calendar_widget"
    android:autoAdvanceViewId="@id/calendar_widget_adapterViewFlipper"
    android:minWidth="250dp"
    android:minHeight="50dp"
    android:minResizeWidth="250dp"
    android:minResizeHeight="50dp"
    android:previewImage="@drawable/calendar_ori_portrait"
    android:resizeMode="horizontal|vertical"
    android:updatePeriodMillis="0"
    android:widgetCategory="home_screen|keyguard"></appwidget-provider>

CalendarWidgetRemoteViewsService

public class CalendarWidgetRemoteViewsService extends RemoteViewsService {

    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new CalendarWidgetRemoteViewsFactory(this.getApplicationContext(), intent);
    }

}

class CalendarWidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {

    private Context mContext;
    private int mAppWidgetId;

    private List<WidgetItem> mWidgetItems = new ArrayList<WidgetItem>();

    public CalendarWidgetRemoteViewsFactory(Context context, Intent intent) {
        mContext = context;
        mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
    }

    @Override
    public void onCreate() {
        // In onCreate() you setup any connections / cursors to your data source. Heavy lifting,
        // for example downloading or creating content etc, should be deferred to onDataSetChanged()
        // or getViewAt(). Taking more than 20 seconds in this call will result in an ANR.

    }

    @Override
    public void onDataSetChanged() {
        // This is triggered when you call AppWidgetManager notifyAppWidgetViewDataChanged
        // on the collection view corresponding to this factory. You can do heaving lifting in
        // here, synchronously. For example, if you need to process an image, fetch something
        // from the network, etc., it is ok to do it here, synchronously. The widget will remain
        // in its current state while work is being done here, so you don't need to worry about
        // locking up the widget.

        //Log.d("CWRVS", "onDataSetChanged begins");

        final int[] ErrorCode = {0};
        mWidgetItems.clear();


        if (!UtilsHelper.isOnline(mContext)){
            ErrorCode[0] = 1;
        }

        if (ErrorCode[0] == 0)
        {
            final CountDownLatch latchSignal = new CountDownLatch(1);

            AuthenticationHelper authenticationHelper = AuthenticationHelper.getInstance(mContext);
            authenticationHelper.acquireTokenSilentlyWithAccountCheck(new AuthenticationCallback() {

                @Override
                public void onSuccess(AuthenticationResult authenticationResult) {
                    //Log.d("AUTH", "onSuccess");
                    final GraphHelper graphHelper = GraphHelper.getInstance();

                    graphHelper.getAllCalendarsEventsSupEqToday(authenticationResult.getAccessToken(), new ICallback<List<WidgetItem>>() {
                        @Override
                        public void success(List<WidgetItem> lwi) {
                            mWidgetItems = lwi;
                            latchSignal.countDown();
                        }

                        @Override
                        public void failure(ClientException ex) {
                            //Log.e("GRAPH", "Error getting events", ex);
                            latchSignal.countDown();
                        }
                    });
                }

                @Override
                public void onError(MsalException exception) {
                    //Log.d("AUTH", "onError");

                    //if ( exception.getErrorCode() == AuthenticationHelper.NO_CLIENT_ACCOUNT_REGISTERED  ){

                    //}
                    ErrorCode[0] = 2;
                    latchSignal.countDown();
                }

                @Override
                public void onCancel() {
                    //Log.d("AUTH", "onCancel");

                    latchSignal.countDown();
                }
            });
            //}



            try{
                latchSignal.await(15, TimeUnit.SECONDS);
            }
            catch (InterruptedException e){
                Log.e("CDN", "CountDownException", e);
            }
        }


        //Sending BroadCast for Error
        Intent ErrorIntent = new Intent(mContext, CalendarWidgetProvider.class);
        ErrorIntent.setAction(CalendarWidgetProvider.ACTION_CALENDAR_DATA_PARTIAL_UPDATE);

        Bundle extras = new Bundle();
        extras.putInt(CalendarWidgetProvider.EXTRA_ERROR_CODE, ErrorCode[0]);
        ErrorIntent.putExtras(extras);
        mContext.sendBroadcast(ErrorIntent);


        //Log.d("CWRVS", "onDataSetChanged ends");



    }


    @Override
    public void onDestroy() {
        // In onDestroy() you should tear down anything that was setup for your data source,
        // eg. cursors, connections, etc.
        mWidgetItems.clear();
    }

    @Override
    public int getCount() {
        return mWidgetItems.size();
    }

    @Override
    public RemoteViews getViewAt(int position) {
        // position will always range from 0 to getCount() - 1.
        // We construct a remote views item based on our widget item xml file, and set the
        //

        if (this.getCount() == 0){
            return null;
        }

        WidgetItem wi =  mWidgetItems.get(position);
        RemoteViews rv = wi.BuildRemoteViews(mContext, position, this.getCount());

        // You can do heaving lifting in here, synchronously. For example, if you need to
        // process an image, fetch something from the network, etc., it is ok to do it here,
        // synchronously. A loading view will show up in lieu of the actual contents in the
        // interim.

        // Return the remote views object.
        return rv;
    }

    @Override
    public RemoteViews getLoadingView() {
        return null;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }


}

我希望flipinterval尊重其价值。

致谢

0 个答案:

没有答案