Android SharedPreferences没有保存

时间:2014-05-16 05:32:18

标签: android sharedpreferences android-appwidget

我正在访问AppWidgetProvider子类中的SharedPreferences,如下所示:

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        Log.d( TAG, "WidgetProvider.onReceive " + intent.getAction() );
        Toast.makeText( context, "WidgetProvider.onReceive " + intent.getAction(), Toast.LENGTH_LONG ); // TOAST NOT WORKING

        Bundle pExtra = intent.getExtras();
        if ( pExtra != null ) {
            SharedPreferences pref = context.getApplicationContext().getSharedPreferences("widget_pref", Context.MODE_PRIVATE );
            int iWidgetId = intent.getExtras().getInt("widgetId");
            int iCount = pref.getInt("widgetCount", 0);
                    // HERE IS THE PROBLEM, iCount will always start from 0!
            for ( int i = 0; i < 10; i++ ) {
                iCount = pref.getInt("widgetCount", 0);
                iCount++;
                pref.edit().putInt("widgetCount", iCount);
                boolean bSaved = pref.edit().commit(); // return TRUE
                bSaved = pref.contains("widgetCount"); // return FALSE
                Log.w(TAG, "WidgetProvider.onReceive: " + iWidgetId + " > " + iCount + " result: " + bSaved);
            }

                    // non-relevant code
            RemoteViews remoteViews = new RemoteViews( context.getPackageName(), R.layout.widget_layout );
            remoteViews.setTextViewText( R.id.hellotextview, "ID: " + iWidgetId + " > " + iCount );
            Intent clickIntent = new Intent( context, WidgetProvider.class );
            clickIntent.setAction("WIDGET_PROVIDER_CLICKED");
            clickIntent.putExtra("widgetId", iWidgetId);
            PendingIntent clickPendingIntent = PendingIntent.getBroadcast( context, 0, clickIntent, 0 );
            remoteViews.setOnClickPendingIntent( R.id.hellolayout, clickPendingIntent );
//          AppWidgetManager.getInstance(context).updateAppWidget( iWidgetId, remoteViews );
//          ComponentName name = new ComponentName(context, WidgetProvider.class);
            ComponentName name = new ComponentName(context.getApplicationContext(), WidgetProvider.class);
            AppWidgetManager.getInstance(context).updateAppWidget(name, remoteViews);
        }
    }

但是,正如您从评论中看到的那样,即使我正在循环并保存iCount,也将始终从默认值开始。即使我只是提交,contains()甚至返回false。我尝试过不同的获取SharedPreferences的方法(直接使用上下文,或者context.getApplicationContext()以及不同的Context.MODE_XXX)

提前致谢!

5 个答案:

答案 0 :(得分:7)

您每次都要创建一个新的SharedPreferences.Editor对象,在进入for循环之前调用pref.edit().缓存SharedPreferences.Editor对象并重新使用该实例。

答案 1 :(得分:2)

更改这两个代码

pref.edit().putInt("widgetCount", iCount);
boolean bSaved = pref.edit().commit();

SharedPreferences.Editor ed = pref.edit();
ed.putInt("widgetCount", iCount);
ed.commit();

因为每当你调用pref.edit()时,它都会创建一个新对象,你会'提交'一个新对象,而不是你已经调用putInt方法的对象。

答案 2 :(得分:2)

编辑您的代码:

我在for循环之前声明了SharedPreferences.Editor对象,然后在循环中重用:

试一试:

SharedPreferences pref = context.getApplicationContext().getSharedPreferences("widget_pref", Context.MODE_PRIVATE );
int iWidgetId = intent.getExtras().getInt("widgetId");
int iCount = pref.getInt("widgetCount", 0);

/**** ADD THIS LINE ****/
SharedPreferences.Editor prefEditor = pref.edit();


// HERE IS THE PROBLEM, iCount will always start from 0!
for ( int i = 0; i < 10; i++ ) {
    iCount = pref.getInt("widgetCount", 0);
    iCount++;

    /** Edit Here Like **/
    prefEditor.putInt("widgetCount", iCount);
    prefEditor.commit();

    //boolean bSaved = prefEditor.commit(); // return TRUE
    bSaved = pref.contains("widgetCount"); // return FALSE

    Log.w(TAG, "WidgetProvider.onReceive: " + bSaved);
}

评论你是否有任何疑问。

答案 3 :(得分:1)

替换:

        SharedPreferences pref = context.getApplicationContext().getSharedPreferences("widget_pref", Context.MODE_PRIVATE );
        int iWidgetId = intent.getExtras().getInt("widgetId");
        int iCount = pref.getInt("widgetCount", 0);

        // HERE IS THE PROBLEM, iCount will always start from 0!
        for ( int i = 0; i < 10; i++ ) {
            iCount = pref.getInt("widgetCount", 0);
            iCount++;
            pref.edit().putInt("widgetCount", iCount);
            boolean bSaved = pref.edit().commit(); // return TRUE
            bSaved = pref.contains("widgetCount"); // return FALSE
            Log.w(TAG, "WidgetProvider.onReceive: " + iWidgetId + " > " + iCount + " result: " + bSaved);
        }

通过

        SharedPreferences pref = context.getApplicationContext().getSharedPreferences("widget_pref", Context.MODE_PRIVATE );

        int iWidgetId = intent.getExtras().getInt("widgetId");
        int iCount = pref.getInt("widgetCount", 0);
                // HERE IS THE PROBLEM, iCount will always start from 0!
        for ( int i = 0; i < 10; i++ ) {
           pref = context.getApplicationContext().getSharedPreferences("widget_pref", Context.MODE_PRIVATE );
            iCount = pref.getInt("widgetCount", 0);
            iCount++;
            pref.edit().putInt("widgetCount", iCount);
            boolean bSaved = pref.edit().commit(); // return TRUE
            bSaved = pref.contains("widgetCount"); // return FALSE
            Log.w(TAG, "WidgetProvider.onReceive: " + iWidgetId + " > " + iCount + " result: " + bSaved);
        }

因为每次想要获取或读取它时都必须采用更新的首选项。

答案 4 :(得分:1)

这个问题已经有了正确答案,即用于输入数据的Editor应该用于提交数据。我只想指出它可以用单行写出来:

pref.edit().putInt("widgetCount", iCount).commit();

这是美好而优雅的,这就是它的意图。您可以多次扩展它:

pref.edit().putInt("data1", data1).putInt("data2", data2).putBoolean("data3", data3).commit();

但是如果你在循环中编写数据,那么你应该首先创建Editor,然后在循环中重用它。由于Editor是本地缓存,因此可以节省访问持久存储的活动。