RuntimeException:无法启动 activity ComponentInfo,NotFoundException

RuntimeException: Unable to start activity ComponentInfo, NotFoundException

我正在尝试通过这个基本示例学习 Retrofit 2。我在尝试将可序列化数据从 activity 传递到 activity...

时遇到问题

你知道为什么吗?

这是我的代码。

logcat:

05-24 00:21:46.215 18156-18156/com.krystian.weatherapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.krystian.weatherapp, PID: 18156
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.krystian.weatherapp/com.krystian.flowerapp.ui.DetailActivity}: android.content.res.Resources$NotFoundException: String resource ID
#0x2
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
   at android.app.ActivityThread.access0(ActivityThread.java:156)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:211)
   at android.app.ActivityThread.main(ActivityThread.java:5373)
   at java.lang.reflect.Method.invoke(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2
   at android.content.res.Resources.getText(Resources.java:340)
   at android.support.v7.widget.ResourcesWrapper.getText(ResourcesWrapper.java:52)
   at android.widget.TextView.setText(TextView.java:4171)
   at com.krystian.flowerapp.ui.DetailActivity.setData(DetailActivity.java:52)
   at com.krystian.flowerapp.ui.DetailActivity.onCreate(DetailActivity.java:47)
   at android.app.Activity.performCreate(Activity.java:5990)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442) 
   at android.app.ActivityThread.access0(ActivityThread.java:156) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:211) 
   at android.app.ActivityThread.main(ActivityThread.java:5373) 
   at java.lang.reflect.Method.invoke(Native Method) 
   at java.lang.reflect.Method.invoke(Method.java:372) 
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020) 
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)

MainActivity.java:

package com.krystian.flowerapp.ui;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

import com.krystian.flowerapp.R;
import com.krystian.flowerapp.adapter.FlowerAdapter;
import com.krystian.flowerapp.controller.RestManager;
import com.krystian.flowerapp.helper.Constants;
import com.krystian.flowerapp.model.Flower;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity implements FlowerAdapter.FlowerClickListener {
@BindView(R.id.recyclerView)
RecyclerView recyclerView;

private RestManager mRestManager;
private FlowerAdapter mFlowerAdapter;

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

    ButterKnife.bind(this);

    configViews();

    mRestManager = new RestManager();
    Call<List<Flower>> listCall = mRestManager.getFlowerService().getAllFlowers();
    listCall.enqueue(new Callback<List<Flower>>() {
        @Override
        public void onResponse(Call<List<Flower>> call, Response<List<Flower>> response) {
            if (response.isSuccessful()) {
                List<Flower> flowerList = response.body();

                for (int i=0; i < flowerList.size(); i++) {
                    Flower flower = flowerList.get(i);
                    mFlowerAdapter.addFlower(flower);
                }
            } else {
                int ac = response.code();
                Log.e("Response code", String.valueOf(ac));
            }
        }

        @Override
        public void onFailure(Call<List<Flower>> call, Throwable t) {

        }
    });
}

private void configViews() {
    recyclerView.setHasFixedSize(true);
    recyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
    recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));

    mFlowerAdapter = new FlowerAdapter(this);

    recyclerView.setAdapter(mFlowerAdapter);
}

@Override
public void onClick(int position) {
    Flower selectedFlower = mFlowerAdapter.getSelectedFlower(position);
    Intent intent = new Intent(MainActivity.this, DetailActivity.class);
    intent.putExtra(Constants.REFERENCE.FLOWER, selectedFlower);
    startActivity(intent);
}
}

DetailActivity.java:

package com.krystian.flowerapp.ui;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.TextView;

import com.krystian.flowerapp.R;
import com.krystian.flowerapp.helper.Constants;
import com.krystian.flowerapp.model.Flower;
import com.squareup.picasso.Picasso;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * Created by: Krystian
 * Date: 23.05.2016.
 */

public class DetailActivity extends AppCompatActivity {
@BindView(R.id.photoImageView)
ImageView photoImageView;
@BindView(R.id.nameTextView)
TextView nameTextView;
@BindView(R.id.idTextView)
TextView idTextView;
@BindView(R.id.categoryTextView)
TextView categoryTextView;
@BindView(R.id.priceTextView)
TextView priceTextView;
@BindView(R.id.instructionsTextView)
TextView instructionsTextView;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_detail);

    ButterKnife.bind(this);

    Intent intent = getIntent();
    Flower flower = (Flower) intent.getSerializableExtra(Constants.REFERENCE.FLOWER);

    setData(flower);
}

private void setData(Flower flower) {
    nameTextView.setText(flower.getName());
    idTextView.setText(flower.getProductId());
    categoryTextView.setText(flower.getCategory());
    priceTextView.setText(String.valueOf(flower.getPrice()));
    instructionsTextView.setText(flower.getInstructions());

    Picasso
            .with(getApplicationContext())
            .load(Constants.HTTP.PHOTO_URL + flower.getPhoto())
            .into(photoImageView);
}
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.krystian.flowerapp">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name="com.krystian.flowerapp.ui.MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name="com.krystian.flowerapp.ui.DetailActivity" />
</application>

导致问题的行位于 DetailActivity 中的第 52 行:

idTextView.setText(flower.getProductId());

setText的声明是:

void setText (int resid)

线索在参数名中,它是一个资源ID,当flower.getProductId()传递给视图的setText方法时,它期待[=14=中的字符串资源] 或表示 int 字符串资源的标识符。并且资源 ID 与 flower class 的实际 getter/method getProductId() 之间发生了混淆。

最简单的解决方法是使用Stringclass的valueOf方法,将flower[=32=的Product ID转换为] 到字符串类型。

idTextView.setText(String.valueOf(flower.getProductId()));