java - 改造 - 当我调用 Intent 打开新 Activity 时应用程序崩溃

标签 java android android-fragments android-intent retrofit

我对 Android 比较陌生,刚刚开始玩 Retrofit。目前我正在制作一个餐厅应用程序。起初,我使用 volley 从服务器获取餐厅列表。我将餐厅信息下载到本地数据库并将其添加到我的mapFragment和restaurantListFragment中。然后我决定开始使用retrofit而不是volley。我成功地用 Retrofit 做了同样的事情 - 在我的两个 fragment 中显示餐馆。

但是现在我遇到了一个奇怪的问题,我认为该问题不应该与改造相关 - 如果我尝试打开一个 Intent ,我的应用程序就会崩溃。当我尝试从中打开 Activity 时,我的抽屉导航崩溃了。我还可以选择在 map 上长按添加餐厅。长按将调用 Intent 并打开 setRestaurantActivity。它也会崩溃。

这是我尝试打开抽屉导航 Activity 时得到的结果。

02-06 11:45:31.862 18777-18777/? D/AndroidRuntime: Shutting down VM
02-06 11:45:31.862 18777-18777/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x5cc97b20)
02-06 11:45:31.862 7010-7080/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-Application: Application crash has been observed. 
02-06 11:45:31.862 7010-7080/com.bluestacks.BstCommandProcessor W/BstCommandProcessor-Application: in sendHttpRequest, requestType is of CRASH_APP type but one of the requiredInfo is NULL, crashedApp = com.bluestacks.BstCommandProcessor.BstCrashedAppInfo@2e75f9cc
02-06 11:45:31.862 18777-18777/? I/Process: Sending signal. PID: 18777 SIG: 9
02-06 11:45:31.862 18777-18777/? D/AndroidRuntime: procName from cmdline: com.weekendcoder.kemo.restaurant
02-06 11:45:31.862 18777-18777/? E/AndroidRuntime: in writeCrashedAppName, pkgName :com.weekendcoder.kemo.restaurant
02-06 11:45:31.862 18777-18777/? D/AndroidRuntime: file written successfully with content: com.weekendcoder.kemo.restaurant StringBuffer : ;com.weekendcoder.kemo.restaurant
02-06 11:45:31.862 18777-18777/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.weekendcoder.kemo.restaurant, PID: 18777
        java.lang.RuntimeException: Parcel: unable to marshal value      com.weekendcoder.kemo.restaurant.model.Restaurant@2e7b673c
        at android.os.Parcel.writeValue(Parcel.java:1266)
        at android.os.Parcel.writeList(Parcel.java:653)
        at android.os.Parcel.writeValue(Parcel.java:1226)
        at android.os.Parcel.writeArrayMapInternal(Parcel.java:618)
        at android.os.Bundle.writeToParcel(Bundle.java:1692)
        at android.os.Parcel.writeBundle(Parcel.java:636)
        at android.support.v4.app.FragmentState.writeToParcel(Fragment.java:148)
        at android.os.Parcel.writeTypedArray(Parcel.java:1133)
        at android.support.v4.app.FragmentManagerState.writeToParcel(FragmentManager.java:563)
        at android.os.Parcel.writeParcelable(Parcel.java:1285)
        at android.os.Parcel.writeValue(Parcel.java:1204)
        at android.os.Parcel.writeArrayMapInternal(Parcel.java:618)
        at android.os.Bundle.writeToParcel(Bundle.java:1692)
        at android.os.Parcel.writeBundle(Parcel.java:636)
        at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2474)
        at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3098)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5021)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
        at dalvik.system.NativeStart.main(Native Method)
02-06 11:45:31.872 6820-12714/system_process I/ActivityManager: Process com.weekendcoder.kemo.restaurant (pid 18777) has died.
02-06 11:45:31.872 6820-12714/system_process W/ActivityManager: Force removing ActivityRecord{2e93b954 u0 com.weekendcoder.kemo.restaurant/.navdraweractivities.MyProfileActivity t11}: app died, no saved state
02-06 11:45:31.872 6820-12714/system_process V/WindowManager: isVisibleLw false for win : Window{2e9a6c20 u0 com.weekendcoder.kemo.restaurant/com.weekendcoder.kemo.restaurant.navdraweractivities.MyProfileActivity}
02-06 11:45:31.872 6820-12714/system_process W/ActivityManager: Force removing ActivityRecord{2e7170c8 u0 com.weekendcoder.kemo.restaurant/.MainActivity t11}: app died, no saved state
02-06 11:45:31.872 6820-12714/system_process D/ActivityManager: TopActivityInfo, pkgName: com.bluestacks.gamepophome activityName: com.bluestacks.gamepophome/com.uncube.launcher3.Launcher callingPackage:   bstSpecialAppKeyboardHandlingEnabled = false
02-06 11:45:31.872 6820-7036/system_process I/WindowState: WIN DEATH: Window{2e9a6c20 u0 com.weekendcoder.kemo.restaurant/com.weekendcoder.kemo.restaurant.navdraweractivities.MyProfileActivity}
02-06 11:45:31.872 6820-7008/system_process I/WindowState: WIN DEATH: Window{2ea83b54 u0 com.weekendcoder.kemo.restaurant/com.weekendcoder.kemo.restaurant.MainActivity}
02-06 11:45:31.872 7023-7023/com.bluestacks.appguidance D/GuidanceScreen: event === app_launch
02-06 11:45:31.872 7023-7023/com.bluestacks.appguidance D/GuidanceScreen: hiding guidance
02-06 11:45:31.872 7023-7023/com.bluestacks.appguidance D/GuidanceScreen: hardKeyboard = 1
02-06 11:45:31.872 7023-7023/com.bluestacks.appguidance D/GuidanceScreen: controllerType === Keyboard
02-06 11:45:31.872 6820-12714/system_process D/ActivityManager: Showing guidance for pkgName: com.bluestacks.gamepophome
02-06 11:45:31.882 6810-6810/? W/SurfaceFlinger: couldn't log to binary event log: overflow.
02-06 11:45:31.882 7023-7023/com.bluestacks.appguidance D/GuidanceScreen: appName: Torque Launcher, currentPkg: com.bluestacks.gamepophome, event: app_launch, controller: Keyboard
02-06 11:45:31.882 7023-7023/com.bluestacks.appguidance D/GuidanceScreen: appName: Torque Launcher
02-06 11:45:31.892 7010-19051/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-httpd: command: ping
02-06 11:45:31.892 7010-19051/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-httpd: response: {"result":"ok"}
02-06 11:45:31.892 7010-19052/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-httpd: command: getdefaultlauncher
02-06 11:45:31.892 7010-19052/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-httpd: response: {"defaultLauncher":"com.bluestacks.gamepophome","result":"ok"}
02-06 11:45:31.902 7010-19053/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-httpd: command: ping
02-06 11:45:31.902 7010-19053/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-httpd: response: {"result":"ok"}
02-06 11:45:31.902 7010-19055/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-httpd: command: ping
02-06 11:45:31.902 7010-19055/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-httpd: response: {"result":"ok"}
02-06 11:45:31.912 7010-19054/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-httpd: command: StopApp com.weekendcoder.kemo.restaurant
02-06 11:45:31.912 7010-19054/com.bluestacks.BstCommandProcessor D/BstCommandProcessor-Application: in isSystemReady, isBootCompleted true External storage status: mounted  External storage dir :/storage/sdcard  isExternalStorageRemovable:true

这就是我的抽屉导航的样子(在我开始使用改造后没有改变),并且之前工作过:

public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();

if (id == R.id.nav_account) {
    // Handle the account action
    Intent accountIntent = new Intent(MainActivity.this, MyProfileActivity.class);
    startActivity(accountIntent);
} else if (id == R.id.nav_contacts) {
    Intent contactsIntent = new Intent(MainActivity.this, FavouriteRestaurantsListActivity.class);
    startActivity(contactsIntent);
} else if (id == R.id.nav_blocked) {
    Intent blockedIntent = new Intent(MainActivity.this, BlockedRestaurantsListActivity.class);
    startActivity(blockedIntent);
} else if (id == R.id.nav_logout) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(R.string.logging_out)
            .setMessage(R.string.logout_yes_no)
            .setCancelable(false)
            .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    logoutUser();
                }
            })
            .setNegativeButton(R.string.no, null);

    AlertDialog alert = builder.show();
    TextView messageText = (TextView) alert.findViewById(android.R.id.message);
    if (messageText != null) {
    messageText.setGravity(Gravity.CENTER);
    }
}

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}

这是从我的 map fragment 调用的 setRestaurantActivity 调用:

                mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {

                @Override
                public void onMapLongClick(final LatLng arg0) {

                    RequestQueue queue = Volley.newRequestQueue(getActivity());
                    String url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + String.valueOf(arg0.latitude) + "," + String.valueOf(arg0.longitude) + "&key=myKey ";

                    // Request a string response from the provided URL.
                    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                            new Response.Listener<String>() {
                                @Override
                                public void onResponse(String response) {
                                    try {
                                        JSONArray jObj = new JSONObject(response).getJSONArray("results").getJSONObject(0).getJSONArray("address_components");

                                        Intent intent = new Intent(getActivity(), SetRestaurantActivity.class);

                                        for (int i = 0; i < jObj.length(); i++) {
                                            String componentName = new JSONObject(jObj.getString(i)).getJSONArray("types").getString(0);
                                            if (componentName.equals("postal_code") || componentName.equals("locality") || componentName.equals("street_number") || componentName.equals("route")
                                                    || componentName.equals("neighborhood") || componentName.equals("sublocality") || componentName.equals("administrative_area_level_2")
                                                    || componentName.equals("administrative_area_level_1") || componentName.equals("country")) {
                                                intent.putExtra(componentName, new JSONObject(jObj.getString(i)).getString("short_name"));
                                            }
                                        }

                                        intent.putExtra("latitude", arg0.latitude);
                                        intent.putExtra("longitude", arg0.longitude);

                                        startActivity(intent);

                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }, new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            int x = 1;
                        }
                    });
                    queue.add(stringRequest);

                }
            });

我的餐厅模型:

import java.io.Serializable;

import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;

public class Restaurant {
    @SerializedName("user_id")
    private String userId;
    @SerializedName("name")
    private String userName;
    @SerializedName("message")
    private String message;
    @SerializedName("image")
    private String thumbnailUrl;
    @SerializedName("latitude")
    private String lat;
    @SerializedName("longitude")
    private String lon;
    @SerializedName("event_date")
    private String date;
    @SerializedName("event_time")
    private String time;
    @SerializedName("id")
    private String id;
    @SerializedName("created_datetime")
    private String createdDateTime;

public Restaurant() {
}

public Restaurant(String name, String thumbnailUrl, String date, String time, String lat, String lon) {
    this.userName = name;
    this.thumbnailUrl = thumbnailUrl;
    this.date = date;
    this.time = time;
    this.lat = lat;
    this.lon = lon;
}

public String getUserName() {
    return userName;
}

public void setUserName(String name) {
    this.userName = name;
}

public String getThumbnailUrl() {
    return thumbnailUrl;
}

public void setThumbnailUrl(String thumbnailUrl) {
    this.thumbnailUrl = thumbnailUrl;
}

public String getLat() {
    return lat;
}

public void setLat(String latitude) {
    this.lat = latitude;
}

public String getLon() {
    return lon;
}

public void setLon(String longitude) {
    this.lon = longitude;
}

public String getDate() {
    return date;
}

public void setDate(String date) {
    this.date = date;
}

public String getTime() {
    return time;
}

public void setTime(String time) {
    this.time = time;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getUserId() {
    return userId;
}

public void setUserId(String userId) {
    this.userId = userId;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public String getCreatedDateTime() {
    return createdDateTime;
}

public void setCreatedDateTime(String createdDateTime) {
    this.createdDateTime = createdDateTime;
}
}

onSavedInstanceState:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    // save the tutorial page (or something else)
    savedInstanceState.putInt("TutPage", tutorialPage);
    savedInstanceState.putBoolean("tutUsed", tutorialUsed);
    // more additions possible
}

编辑后的餐厅模型 - 工作版本:

import android.os.Parcel;
import android.os.Parcelable;

import java.io.Serializable;

import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;

public class Restaurant implements Parcelable{
@SerializedName("user_id")
private String userId;
@SerializedName("name")
private String userName;
@SerializedName("message")
private String message;
@SerializedName("image")
private String thumbnailUrl;
@SerializedName("latitude")
private String lat;
@SerializedName("longitude")
private String lon;
@SerializedName("event_date")
private String date;
@SerializedName("event_time")
private String time;
@SerializedName("id")
private String id;
@SerializedName("created_datetime")
private String createdDateTime;

public Restaurant() {
}

public Restaurant(String name, String thumbnailUrl, String date, String time, String lat, String lon) {
    this.userName = name;
    this.thumbnailUrl = thumbnailUrl;
    this.date = date;
    this.time = time;
    this.lat = lat;
    this.lon = lon;
}

protected Restaurant(Parcel in) {
    userId = in.readString();
    userName = in.readString();
    message = in.readString();
    thumbnailUrl = in.readString();
    lat = in.readString();
    lon = in.readString();
    date = in.readString();
    time = in.readString();
    id = in.readString();
    createdDateTime = in.readString();
}

public static final Creator<Restaurant> CREATOR = new Creator<Restaurant>() {
    @Override
    public Restaurant createFromParcel(Parcel in) {
        return new Restaurant(in);
    }

    @Override
    public Restaurant[] newArray(int size) {
        return new Restaurant[size];
    }
};

public String getUserName() {
    return userName;
}

public void setUserName(String name) {
    this.userName = name;
}

public String getThumbnailUrl() {
    return thumbnailUrl;
}

public void setThumbnailUrl(String thumbnailUrl) {
    this.thumbnailUrl = thumbnailUrl;
}

public String getLat() {
    return lat;
}

public void setLat(String latitude) {
    this.lat = latitude;
}

public String getLon() {
    return lon;
}

public void setLon(String longitude) {
    this.lon = longitude;
}

public String getDate() {
    return date;
}

public void setDate(String date) {
    this.date = date;
}

public String getTime() {
    return time;
}

public void setTime(String time) {
    this.time = time;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getUserId() {
    return userId;
}

public void setUserId(String userId) {
    this.userId = userId;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public String getCreatedDateTime() {
    return createdDateTime;
}

public void setCreatedDateTime(String createdDateTime) {
    this.createdDateTime = createdDateTime;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeString(userId);
    parcel.writeString(userName);
    parcel.writeString(message);
    parcel.writeString(thumbnailUrl);
    parcel.writeString(lat);
    parcel.writeString(lon);
    parcel.writeString(date);
    parcel.writeString(time);
    parcel.writeString(id);
    parcel.writeString(createdDateTime);
}
}

最佳答案

来自行:

java.lang.RuntimeException: Parcel: unable to marshal value      com.weekendcoder.kemo.restaurant.model.Restaurant@2e7b673c

有人可能会推断,Restaurant 对象想要写入包裹,但这不可能发生,因为 Restaurant 不可包裹。

使 Restaurant 类实现 Parcelable 接口(interface)可以解决该问题。

关于java - 改造 - 当我调用 Intent 打开新 Activity 时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42066627/

相关文章:

java - 在android中逐行读取文件后如何在UI上显示SetText值?

android - 如何在android中的clickListener上增加/减少STROKE宽度

java - Android:在 fragment 中按下后退按钮时如何隐藏底部工作表?

java - 了解选项卡中从 Activity 到 fragment 的基本转换

java - 日志记录和普通文件写入有什么区别?

java - 为什么我的 @PersistenceContext EntityManager 上抛出 NullPointerException?

使用 TagSoup 解析页面 URL 以创建 DOM 时出现 java IOException

android - 如何绑定(bind) startActivity() 需要 FLAG_ACTIVITY_NEW_TASK?

java - 从扩展 Activity 的 MainActivity 类调用扩展 Fragment 的类 Fragment

java - SSL 握手失败错误