【问题标题】:Saving objects on Android在 Android 上保存对象
【发布时间】:2014-03-14 13:45:04
【问题描述】:

我正在尝试保存一个序列化的计时器对象并检索它。计时器需要完全恢复到创建时的状态。

计时器工作得很好,但是当应用程序被销毁时,我的计时器及其所有数据也会被销毁。

编辑:调试日志显示 FileNotFoundException:打开失败(只读文件系统)

  • 我的清单中有使用权限
  • 我没有尝试写入 SD 卡,我想在本地用户的 android 上创建文件。 .......

我的计时器类实现了序列化

并且 OnCreate 我的应用程序尝试连接到一个对象输入流和一个文件输入流;检索对象,将其转换为 Timer 并分配它。

每次更新时都会存储计时器。

定时器类代码

package com.example.theworkingbutton;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

import android.widget.Button;

public class Timer implements Serializable {

    private static final long serialVersionUID = 1L;

    public Timer(int timerState){
        this.timerState = timerState;

    }

    public int timerState = 0;
    public long timerStart = 0;
    public long timerEnd = 0;
    public long timeAccumulated = 0;

    public long totalSeconds = 0;
    public long hours = 0;
    public long minutes = 0;
    public long seconds = 0;

    public String realTimeSeconds = "null";
    public String realTimeMinutes = "null";
    public String realTimeHours = "null";
    public String timeString = "No time avalible";

    Button button;

    public void preform(){

        if(timerState == 0){

            timerStart =  System.nanoTime();        
            timerState = 1;

        } else if (timerState == 1) {

            timerEnd = System.nanoTime();
            timeAccumulated = timerEnd - timerStart + timeAccumulated;

            totalSeconds = TimeUnit.SECONDS.convert(timeAccumulated, TimeUnit.NANOSECONDS);
            hours = (totalSeconds / 3600);
            minutes = (totalSeconds % 3600) / 60;
            seconds = (totalSeconds % 60);

            realTimeHours = Long.toString(hours);
            realTimeSeconds = Long.toString(seconds);
            realTimeMinutes = Long.toString(minutes);
            timeString = "Hours: " + realTimeHours + " Minutes: " + realTimeMinutes + " Seconds: " + realTimeSeconds;

            timerState = 0;
        }
    }
}

结束定时器类代码

ONCREATE 代码

@Override
    protected void onCreate(Bundle savedInstanceState){

        //make screen
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        locManager =(LocationManager)getSystemService(Context.LOCATION_SERVICE);
        locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L,
            500.0f, locationListener);

       //get buttons / turn them red
        workingButton = (Button) findViewById(R.id.timer_button);
        officeButton = (Button) findViewById(R.id.office_button);
        drivingButton = (Button) findViewById(R.id.drive_button);
        showingButton = (Button) findViewById(R.id.showing_button);
        prospectingButton = (Button) findViewById(R.id.prospect_button);
        listingButton = (Button) findViewById(R.id.listing_button);

        listingButton.getBackground().setColorFilter(0xffffff00, PorterDuff.Mode.MULTIPLY);
        workingButton.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
        drivingButton.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
        officeButton.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
        showingButton.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
        prospectingButton.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);


      //set up our map
        GoogleMap monthlyMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
        Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (location != null) {
            location.getLatitude();
            location.getLongitude();
        }
        monthlyMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        monthlyMap.setMyLocationEnabled(true);
        monthlyMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),location.getLongitude()), 15 ));


        try{
        @SuppressWarnings("resource")
        ObjectInputStream is = new ObjectInputStream(new FileInputStream("TheWorkingButtonSaves.txt"));
        Timer timerOne = (Timer) is.readObject();
        workingTimer = timerOne;}
        catch (Exception e){
            e.printStackTrace();
        }
    }

创建代码结束

我如何尝试保存

 Timer workingTimer;
    public void startWorking(View view){

        if (workingTimer == null){
            workingTimer = new Timer(working);}

        //Layout Views
        workingButton = (Button) findViewById(R.id.timer_button);
        TextView amountOfTime = (TextView) findViewById(R.id.time_spent);

        if(drivingTimer.timerState == 1){
            drivingSomewhere(findViewById(R.id.drive_button));
        }

        workingTimer.preform();


        // Button Colors
         if (workingTimer.timerState == 0 ){     //(TIMERS OFF)
            workingButton = (Button) findViewById(R.id.timer_button);
            workingButton.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);

         } 
         else {  //(TIMERS ON)
             workingButton.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);
         }

         //save
         try {

            FileOutputStream fs = new FileOutputStream ("TheWorkingButtonSaves.txt");
            ObjectOutputStream os = new ObjectOutputStream(fs);

            os.writeObject(workingTimer);
            os.close();

        } catch (Exception e) {
            e.printStackTrace();
            }

         //Display Time to user
         amountOfTime.setText(workingTimer.timeString);
    }   

结束我如何保存

【问题讨论】:

  • 当你尝试执行上述代码时会发生什么。
  • @B.J.Smegma 它运行,没有错误。但是当我结束应用程序并重新打开它时,我的计时器丢失了。
  • 您是否尝试过调试代码。在反序列化计时器的行上放置一个断点。然后检查它的状态。
  • @B.J.Smegma 当然。我感觉文件没有被创建。我正在视图调用中写入文件/对象输出流(当按下按钮时,计时器开始或停止。)......我将在编辑中添加整个代码,所以你可以看到。

标签: java android fileoutputstream objectinputstream objectoutputstream


【解决方案1】:

您可以使用 SharedPreferences 保存计时器的值。

   SharedPreferences saveTimer= getSharedPreferences("saveTimer", Activity.MODE_PRIVATE);
   SharedPreferences.Editor editor= timeSaved.edit();
   // There's also putLong and putFloat
   editor.putInt("saveTimer", INT_NAME_1);
   editor.commit();

然后您使用

检索它
    SharedPreferences getTimer = getSharedPreferences("saveTimer", Activity.MODE_PRIVATE);
    int INT_NAME_2 = getTimer.getInt("saveTimer", 0);

现在您有一个 int(或 float 或 long)值,您可以将其放回并从您开始的地方开始。 (您也可以使用它来检索您在其他活动中保存的任何内容的值)

【讨论】:

  • 我试图保存一个对象,而不是一个原语
【解决方案2】:

如果有帮助,请参阅以下链接。在我看来,最好让平台来处理序列化/反序列化,而不是我们来处理。

Handling runtime changes

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多