从类字符串中打开一个新活动。类null

时间:2016-03-07 13:53:11

标签: android

在一个片段中我想打开一个新活动,但是类是由字符串提取的。 在toast中接收myclass.class,但是没有打开一个新类,如果从新类中更改“c”,则代码可以正常工作。 谢谢。

代码:

if (item instanceof Movie) {
            Log.d(TAG, "Item: " + item.toString());
            String page = item.toString();
            String pageFinal = page + ".class";
            Toast.makeText(getActivity(), item.toString(),
                    Toast.LENGTH_LONG).show();

            Class<?> c = null;
            if(pageFinal != null) {
                try {
                    c = Class.forName(pageFinal);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
            Intent intent = new Intent(getActivity(), c);
            getActivity().startActivity(intent);

        }

日志:

    03-07 08:42:19.872 18138-18138/ro.vrt.videoplayerstreaming W/System.err:            Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
03-07 08:42:19.872 18138-18138/ro.vrt.videoplayerstreaming D/AndroidRuntime: Shutting down VM
03-07 08:42:19.872 18138-18138/ro.vrt.videoplayerstreaming E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: ro.vrt.videoplayerstreaming, PID: 18138
                                                                             java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Class.getName()' on a null object reference
                                                                                 at android.content.ComponentName.<init>(ComponentName.java:129)
                                                                                 at android.content.Intent.<init>(Intent.java:4449)
                                                                                 at ro.vrt.videoplayerstreaming.MainFragment$ItemViewClickedListener.onItemClicked(MainFragment.java:71)
                                                                                 at android.support.v17.leanback.widget.ListRowPresenter$ListRowPresenterItemBridgeAdapter$1.onClick(ListRowPresenter.java:243)
                                                                                 at android.view.View.performClick(View.java:5198)
                                                                                 at android.view.View$PerformClick.run(View.java:21147)
                                                                                 at android.os.Handler.handleCallback(Handler.java:739)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                 at android.os.Looper.loop(Looper.java:148)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-07 08:42:22.304 18138-18138/ro.vrt.videoplayerstreaming I/Process: Sending signal. PID: 18138 SIG: 9

编辑:

Movie.java

public class Movie {

private static final String TAG = Movie.class.getSimpleName();

static final long serialVersionUID = 727566175075960653L;
private long id;
private String title;
private String studio;
private String description;
private String cardImageUrl;

public String getCardImageUrl() {
    return cardImageUrl;
}

public void setCardImageUrl(String cardImageUrl) {
    this.cardImageUrl = cardImageUrl;
}
public Movie() {
}
public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}
public long getId() {
    return id;
}

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

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getStudio() {
    return studio;
}

public void setStudio(String studio) {
    this.studio = studio;
}

@Override
public String toString() {
    /*
    return "Movie{" +
            "id=" + id +
            ", title='" + title + '\'' +
            '}';
            */
    return title;
}
public URI getCardImageURI() {
    try {
        return new URI(getCardImageUrl());
    } catch (URISyntaxException e) {
        return null;
    }
}

}

2 个答案:

答案 0 :(得分:5)

当您使用Class.forName(className)方法时,必须使用您的包名称和className名称构建Class而不使用.class扩展名。

对于ro.movieapp.activities.MovieActivity.class,您的通话应该是这样的:Class.forName("ro.movieapp.activities.MovieActivity")

话虽如此,这样做是一个非常糟糕的主意,因为它是一个容易出错的问题(你的问题就是一个很好的例子)。您应该在Class对象中保留对您的活动Movie的引用。

我的建议是做这样的事情:

class Movie {

    private Class<?> activityClass;

    public <C extends AppCompatActivity> void setActivityClass(Class<C> activityClass) {
        this.activityClass = activityClass;
    }

    @SuppressWarnings("unchecked")
    public <C extends AppCompatActivity> Class<C> getActivityClass() {
        return (Class<C>) activityClass;
    }
}

...

final Movie movie = new Movie();
movie.setActivityClass(MovieActivity.class);

...

final Intent intent = new Intent(getActivity(), movie.getActivityClass());
startActivity(intent);

答案 1 :(得分:3)

Class.forName方法采用类名参数,该参数必须是类的完整路径。

EG。如果您的活动位于包com.example.activity.SampleActivity

那么方法应该像

一样调用
Class<?> c=Class.forName("com.example.activity.SampleActivity");

确保从page.toString()获得正确的类名。