访问片段后台任务中的资源经常返回IllegalStateException异常

5

我正在进行一个异步网络请求来获取评论和预告片。

如果存在评论和预告片,则将它们设置为TextView文本。如果没有评论,则将文本视图测试设置为strings.xml文件中预定义的字符串变量"No reviews"(message_no_reviews)

现在,为了显示当没有评论可用时的文本,我使用以下方法进行提取

getResources().getString(R.string.message_no_reviews)

问题在于调用 getResources().getString(R.string.message_no_reviews) 返回了 java.lang.IllegalStateException: Fragment MovieDetailFragment{1fdfd76} not attached to Activity 异常,而调用 getResources().getString(R.string.api_key) 没有引起任何异常。

以下是代码片段。

public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getReviews();
        getTrailers();
    } 

public void getReviews(){


    Call<JsonObject> getReviewsCall = apiService.getReview(movie.getId(),getResources().getString(R.string.api_key));


    getReviewsCall.enqueue(new Callback<JsonObject>() {
        @Override
        public void onResponse(Response<JsonObject> response, Retrofit retrofit) {

            if (response.body() != null) {

                JsonArray reviews=(JsonArray) response.body().get("results");
                System.out.println(reviews);
                if(reviews.size()>0) {
                    tvReviewText.setText(((JsonObject) reviews.get(0)).get("content").getAsString());
                    tvReviewAuthor.setText(((JsonObject) reviews.get(0)).get("author").getAsString());

                }
                else{

                    tvReviewAuthor.setText(getResources().getString(R.string.message_no_reviews));
                    tvReviewText.setText("");
                }

            }

        }

        @Override
        public void onFailure(Throwable t) {

        }

    });


}

有何想法是为什么会发生这种情况?
以下是日志记录。
 FATAL EXCEPTION: main
 Process: com.vipin.www.popularmovies, PID: 21580
 java.lang.IllegalStateException: Fragment MovieDetailFragment{1fdfd76} not attached to Activity
     at android.support.v4.app.Fragment.getResources(Fragment.java:636)
     at com.vipin.www.popularmovies.MovieDetailFragment$2.onResponse(MovieDetailFragment.java:168)
     at retrofit.ExecutorCallAdapterFactory$ExecutorCallback$1.run(ExecutorCallAdapterFactory.java:86)
     at android.os.Handler.handleCallback(Handler.java:739)
     at android.os.Handler.dispatchMessage(Handler.java:95)
     at android.os.Looper.loop(Looper.java:135)
     at android.app.ActivityThread.main(ActivityThread.java:5221)
     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:899)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

请将您的Logcat也放在其中.............. - sushildlh
将需要一个Activity的代码放置在Fragment的onAttach方法内或之后,这样应该可以修复至少其中一个提到的错误。 - OneCricketeer
@cricket_007 这几乎不是什么问题。正如您所看到的,有2个调用getResources()的方法。getResources().getString(R.string.api_key)可以正常工作,但是getResources().getString(R.string.message_no_reviews)会抛出异常。 - vipin agrahari
@cricket_007 但是如果你的Fragment没有被填充,那么这将抛出一个异常。 - pratham kesarkar
1
你知道你可以直接使用 tvReviewAuthor.setText(R.string.message_no_reviews); 吗?请尝试一下。 - OneCricketeer
你什么时候调用get review函数? - Hala.M
3个回答

5
你的片段没有依附于活动,这意味着:由于你从按钮中进行了网络调用,它创建了另一个后台线程,然后你要么将片段推入回退栈中,要么将其从活动中移除,因此,当响应到达 onResponse 方法时,它的上下文不可用。
所以你应该使用:
Fragment.this.getResources().getString(R.string.message_no_reviews)); 

或者在onCreate()和onDestroy()中创建一个布尔值来判断片段是否已经附加。


谢谢,这节省了我不少麻烦! - paul590
当我在进行这个操作时,它会提示 android.support.V4.app.Fragment 不是一个封闭类。 - Mansuu....
@Mansuu.... 这是因为你正在使用 android.support.V4.app.Fragment。你应该在使用代码的地方使用你的片段类。 - Phuong Dao

1

tvReviewAuthor.setText(getActivity().getResources().getString(R.string.message_no_reviews)); 这应该可以起作用了。您需要上下文对象来访问字符串资源。


我尝试使用它,但在大多数情况下getActivity()返回null。 - vipin agrahari

0
使用 onAttach() 方法来知道你的 Fragment 已经附加到 Activity 上,并且在其中获取上下文,然后使用它来调用其他方法,就像这样。
    @Override
public void onAttach(Context context) {
    super.onAttach(context);
    activity = context;
}

然后你可以这样做

tvReviewAuthor.setText(activity.getResources().getString(R.string.message_no_reviews));

这到底有什么不同? - pratham kesarkar
同时,您正在创建一个内存泄漏的空间,即Activity对象在Fragment对象未被销毁之前不会被销毁。 - pratham kesarkar
在这种情况下,是在onAttach()方法中接收的,这可能是一个错误,即片段未附加。 - Vivek Mishra
@vipinagrahari 抱歉,我在回答中漏掉了一个部分,应该使用context而不是getActivity()。我已经在回答中更新了。 - Vivek Mishra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接