尝试使用 SharedPreferences 存储和检索应用程序数据,但它没有返回所需的数据

Posted

技术标签:

【中文标题】尝试使用 SharedPreferences 存储和检索应用程序数据,但它没有返回所需的数据【英文标题】:Trying to store and retrieve App data using SharedPreferences, but it's not returning desired data 【发布时间】:2020-05-17 07:47:48 【问题描述】:

我正在尝试检索每个特定帖子(纬度和经度)的位置,并且我正在通过以下方式执行此操作,请参见下面的代码。我不明白为什么会出现此错误:

无法将 java.lang.String 类型的对象转换为 com.e.events.Model.Post 类型

我在其他活动中使用过这段代码,它工作得很好。

我需要做的是因为每个帖子都有自己特定的postid,我想将其存储在 SharedPreferences 中,然后通过 Firebase 查找特定的postid 并返回该帖子的特定位置纬度和经度。任何人都可以向我解释为什么我会收到此错误?

MapsActivityUser.java

public class MapsActivityUser extends FragmentActivity implements OnMapReadyCallback 

    String postid;
    private GoogleMap map;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps_user);

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        SharedPreferences preferences = getApplicationContext().getSharedPreferences("PREFS", Context.MODE_PRIVATE);
        postid = preferences.getString("postid", "none");
    

    @Override
    public void onMapReady(GoogleMap googleMap) 
        map = googleMap;

        final DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts").child(postid);
        reference.addValueEventListener(new ValueEventListener() 
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) 
                    Post post = snapshot.getValue(Post.class);
                    if (post != null) 
                        double latitude = post.getLocation().getLatitude();
                        double longitude = post.getLocation().getLongitude();

                        LatLng location = new LatLng(latitude, longitude);
                        map.addMarker(new MarkerOptions().position(location).title("Event location"));
                        map.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 10));
                     else 
                        Toast.makeText(MapsActivityUser.this, "Event doesn't have location on Map", Toast.LENGTH_SHORT).show();
                    
                
            

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) 

            
        );
    

Post.java

public class Post 

    private String postid;
    private String postimage;
    private String description;
    private String publisher;
    private String text_event;
    private String text_location;
    private String text_date_time;
    private Long timestamp;
    private double Latitude;
    private double Longitude;
    private LocationHelper locationHelper;

    public Post(String description, String postId, String postImage, String publisher, Long timestamp,
                String text_event, String text_location, String text_date_time, double latitude, double longitude, LocationHelper location) 
        this.postid = postid;
        this.postimage = postimage;
        this.description = description;
        this.publisher = publisher;
        this.text_event = text_event;
        this.text_location = text_location;
        this.text_date_time = text_date_time;
        this.timestamp = timestamp;
        Latitude = latitude;
        Longitude = longitude;
        this.locationHelper = location;
    

    public Post() 
    

    public String getPostid() 
        return postid;
    

    public void setPostid(String postid) 
        this.postid = postid;
    

    public String getPostimage() 
        return postimage;
    

    public void setPostimage(String postimage) 
        this.postimage = postimage;
    

    public String getDescription() 
        return description;
    

    public void setDescription(String description) 
        this.description = description;
    

    public String getPublisher() 
        return publisher;
    

    public void setPublisher(String publisher) 
        this.publisher = publisher;
    

    public String getText_event() 
        return text_event;
    

    public void setText_event(String text_event) 
        this.text_event = text_event;
    

    public String getText_location() 
        return text_location;
    

    public void setText_location(String text_location) 
        this.text_location = text_location;
    

    public String getText_date_time() 
        return text_date_time;
    

    public void setText_date_time(String text_date_time) 
        this.text_date_time = text_date_time;
    

    public Long getTimestamp() 
        return timestamp;
    

    public void setTimestamp(Long timestamp) 
        this.timestamp = timestamp;
    

    public double getLatitude() 
        return Latitude;
    

    public void setLatitude(double latitude) 
        Latitude = latitude;
    

    public double getLongitude() 
        return Longitude;
    

    public void setLongitude(double longitude) 
        Longitude = longitude;
    

    public LocationHelper getLocation() 
        return locationHelper;
    

    public void setLocation(LocationHelper location) 
        this.locationHelper = location;
    

LocationHelper.java

public class LocationHelper 

    private double Latitude;
    private double Longitude;

    public LocationHelper(double latitude, double longitude) 
        Latitude = latitude;
        Longitude = longitude;
    

    public LocationHelper() 
    

    public double getLatitude() 
        return Latitude;
    

    public void setLatitude(double latitude) 
        Latitude = latitude;
    

    public double getLongitude() 
        return Longitude;
    

    public void setLongitude(double longitude) 
        Longitude = longitude;
    

Logcat

java.lang.NullPointerException:尝试调用虚拟方法 'com.e.events.Model.LocationHelper com.e.events.Model.Post.getLocation()' 在空对象引用上 在 com.e.events.Map.MapsActivityUser$1.onDataChange(MapsActivityUser.java:53) 在 com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.2.0:75) 在 com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.2.0:63) 在 com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.2.0:55) 在 android.os.Handler.handleCallback(Handler.java:907) 在 android.os.Handler.dispatchMessage(Handler.java:105) 在 android.os.Looper.loop(Looper.java:216) 在 android.app.ActivityThread.main(ActivityThread.java:7625) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

【问题讨论】:

【参考方案1】:

检查您的查询后,我可以看到您通过了post_id,因此它将直接为您提供发布数据。你不需要遍历DataSnapshot

reference.addValueEventListener(new ValueEventListener() 
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
        Post post = dataSnapshot.getValue(Post.class);
        if (post != null) 
            double latitude = post.getLocation().getLatitude();
            double longitude = post.getLocation().getLongitude();

            LatLng location = new LatLng(latitude, longitude);
            map.addMarker(new MarkerOptions().position(location).title("Event location"));
            map.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 10));
         else 
            Toast.makeText(MapsActivityUser.this, "Event doesn't have location on Map", Toast.LENGTH_SHORT).show();
        
    

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) 

    
);

修改这样的东西:

经纬度不用加

public class Post 

    private String postid;
    private String postimage;
    private String description;
    private String publisher;
    private String text_event;
    private String text_location;
    private String text_date_time;
    private Long timestamp;
    private Location locationHelper;

    public Post(String description, String postId, String postImage, String publisher, Long timestamp,
                String text_event, String text_location, String text_date_time, double latitude, double longitude, LocationHelper location) 
        this.postid = postid;
        this.postimage = postimage;
        this.description = description;
        this.publisher = publisher;
        this.text_event = text_event;
        this.text_location = text_location;
        this.text_date_time = text_date_time;
        this.timestamp = timestamp;
        Latitude = latitude;
        Longitude = longitude;
        this.locationHelper = location;
    

    public Post() 
    

    public String getPostid() 
        return postid;
    

    public void setPostid(String postid) 
        this.postid = postid;
    

    public String getPostimage() 
        return postimage;
    

    public void setPostimage(String postimage) 
        this.postimage = postimage;
    

    public String getDescription() 
        return description;
    

    public void setDescription(String description) 
        this.description = description;
    

    public String getPublisher() 
        return publisher;
    

    public void setPublisher(String publisher) 
        this.publisher = publisher;
    

    public String getText_event() 
        return text_event;
    

    public void setText_event(String text_event) 
        this.text_event = text_event;
    

    public String getText_location() 
        return text_location;
    

    public void setText_location(String text_location) 
        this.text_location = text_location;
    

    public String getText_date_time() 
        return text_date_time;
    

    public void setText_date_time(String text_date_time) 
        this.text_date_time = text_date_time;
    

    public Long getTimestamp() 
        return timestamp;
    

    public void setTimestamp(Long timestamp) 
        this.timestamp = timestamp;
    


    public Location getLocation() 
        return locationHelper;
    

    public void setLocation(Location location) 
        this.locationHelper = location;
    

【讨论】:

我更改了代码以反映您上面的代码,但现在我只收到 Toast 消息。地图上没有显示应有的标记。所有帖子都清楚地保存了位置纬度和经度 请记录您在dataSnapshot中检索到的数据 好吧,我刚刚在应用程序崩溃时发布了 logcat,它说 post.getLocation 为空,但我不知道为什么会这样,因为我有 LocationHelper 存储类位置数据。我在上面贴了logcat D/: onDataChange: This is what it returnsDataSnapshot key = -LzmZfxVKI167NeI5fSH, value = null 这是我得到的,但是如果我有 LocationHelper 模型类和 Post 模型类,为什么会这样? 抱歉回复晚了,但是你需要修改你的模型类

以上是关于尝试使用 SharedPreferences 存储和检索应用程序数据,但它没有返回所需的数据的主要内容,如果未能解决你的问题,请参考以下文章

在Android中的SharedPreferences中存储数组的最有效方法是什么?

MarkAndroid应用开发SharedPreferences存储数据的使用方法

SharedPreferences会在使用前不断删除

使用SharedPreferences进行数据存储

使用 SharedPreferences 保存字符串

安卓开发之文件存储SharedPreferences