繁体   English   中英

我升级到Android Studio 2.3.3,并且一个旧的,没有错误的程序现在出现错误:“片段应该是静态的……”

[英]I upgraded to Android Studio 2.3.3 and an old, bug-free program now gives error: “Fragments should be static…”

错误的全文为:

C:\\Users\\Dov\\Google Drive\\AndroidStudioProjects\\FlagQuiz - Copy (2)\\app\\src\\main\\java\\com\\dslomer64\\flagquiz\\ QuizFragment.java

Error: Fragments should be static such that they can be re-instantiated by the system, and anonymous classes are not static [ValidFragment]

更糟糕的是,它并没有告诉我错误所在的行。由于上面提到的原因,我曾假设QuizFragment有错误,但是怎么办? 因此,我得出的结论是,提到QuizFragment只是为了表明错误所在的类。

另外,请注意,黄色正方形显示的是没有行标记有错误。 在此处输入图片说明

我在下面不完整代码段的注释中的3个地方找到了“匿名”一词。

DialogFragment quizResults = new DialogFragment() // anonymously **********    
                       // extend DialogFragment class
{
  @Override public Dialog onCreateDialog(Bundle bundle)
  { 
    ...
     AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
     builder.setPositiveButton
     (
        R.string.reset_quiz,
        new DialogInterface.OnClickListener()
        {
            public void onClick(DialogInterface dialog, int id)
            { 
                resetQuiz(); 
             }
         } // end anonymous inner class *******************
     ); 
     return builder.create(); // return the AlertDialog

  } // end method onCreateDialog

}; // end DialogFragment anonymous inner class ****************

DialogFragment quizResults = new DialogFragment()或包含匿名内部类的builder的定义有什么问题(从AS 2.3.3开始;升级之前没有什么问题)?

如果是这样,为什么没有编译错误? 在这种情况下,如何解决该问题?

(我不想只是开始破解我没有写的代码[我从一个作者那里收到项目并进行了许多修改],因为至少有3个可以想到的起点,也许没有一个可以解决错误。

升级前没有任何问题

最有可能的是。 Android Studio之前并未抱怨您的代码,但是无论如何它可能无法正常工作。 所发生的变化是,现在Android Studio指出了问题,而不是您发现测试的难题。

是否有问题... DialogFragment quizResults = new DialogFragment()

是。 无法重新创建片段。

因此,当用户旋转屏幕或更改语言环境,进入夜间模式或进行其他任何可能的配置更改时,Android销毁片段并尝试重新创建它时,它就不会这样做。 只有问题中的代码行才能重新创建片段,而这些代码行是您的,而不是框架的,并且不了解它们。

您有可能通过android:configChanges阻止了活动的普通销毁和重新创建周期来解决此android:configChanges 那本身通常是一种反模式,但是如果您合法地需要android:configChanges并正确使用它,则应该可以消除此Lint错误。

在这种情况下,如何解决该问题?

quizResults创建常规Java类,扩展DialogFragment并包括您的代码。 然后,使用该Java类。

错误的部分如下:

DialogFragment quizResults = new DialogFragment() {

    @Override
    public Dialog onCreateDialog(Bundle bundle) {

在其中定义DialogFragment的匿名子类。 这是Android 2.3.3中新的lint检查所建议的使用片段的错误方法。

为什么? 如果您正在使用Activity的FragmentManager则实例化此类片段将导致问题。

有问题的情况如下:当调用Activity#saveInstanceState(Bundle outState)FragmentManager将尝试保存Fragment的状态。 随后,当Activity的状态恢复时, FragmentManager将尝试重新创建您的Fragment(使用no-args构造函数)并将其状态设置为以前的状态。 如果使用Fragment的匿名子类,则无法实现。

Henec,片段必须具有无参数构造函数,并且实例化它们的首选方法是使用静态工厂方法。 可以使用Fragment#setArguments(Bundle bundle)代替匿名子类:

QuizFragment.java中

public static QuizFragment instantiate(Bundle args) {
    QuizFragment frag = new QuizFragment();
    frag.setArguments(args);
    return frag;
}

我遇到了同样的问题。 我将匿名DialogFragment类转换为常规类:

public  DialogFragment instantiate(Bundle args){  
 DialogFragment quizResults = new DialogFragment();

 quizResults.setArguments(args);
 Dialog aDialog = createDialog(args);
 aDialog.show();

 return quizResults;
}

// create an AlertDialog and return it 
public Dialog createDialog(Bundle bundle){
  AlertDialog.Builder builder =
   new AlertDialog.Builder(getActivity());
     builder.setCancelable(false);

     builder.setMessage(
     getResources().getString(
       R.string.results, totalGuesses, (1000 / (double) totalGuesses)));

    // "Reset Quiz" Button            
builder.setPositiveButton(R.string.reset_quiz,
 new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int id)
{
  resetQuiz();
}
} // end anonymous inner class
  ); // end call to setPositiveButton

return builder.create(); // return the AlertDialog
} // end method createDialog

onClick(View v)下的原始代码块:

///////////////////////////////////////////////////////////////////
 DialogFragment quizResults = new DialogFragment()
  {
    // create an AlertDialog and return it
    @Override
    public Dialog onCreateDialog(Bundle bundle)
    {
       AlertDialog.Builder builder =
          new AlertDialog.Builder(getActivity());
          builder.setCancelable(false);

          builder.setMessage(
          getResources().getString(R.string.results, totalGuesses, (1000 / (double) totalGuesses)));

          // "Reset Quiz" Button
          builder.setPositiveButton(R.string.reset_quiz,
             new DialogInterface.OnClickListener()
             {
                public void onClick(DialogInterface dialog, int id)
                {
                   resetQuiz();
                }
             } // end anonymous inner class
           ); // end call to setPositiveButton

          return builder.create(); // return the AlertDialog
       } // end method onCreateDialog

替换为实例化DialogFragment的调用,如下所示:

    DialogFragment quizResults = instantiate(mSavedInstanceState);   

感谢@Commonsware和@David Rawson,我设法通过将编译器掌握的所有内容更改为static ,使之与myDialogClassstatic内部类一起使用,其中包括几种方法以及许多(每个?)变量。

这带来了一个问题:

public static void loadNextFlag() 
    {
...
    // display current question number--2nd and 3rd parameters are INPUT into the xml statement

    questionNumberTextView.setText
         (correctAnswers + 1) + //was ,
         "/" + FLAGS_IN_QUIZ);

     //        AssetManager assets = getActivity().getAssets();

...
} // end method loadNextFlag

格式化questionNumberTextView的行必须更改为

questionNumberTextView.setText(
                              (""  + (correctAnswers + 1) 
                               "/" + FLAGS_IN_QUIZ);

因为原来

questionNumberTextView.setText(getResources().getString
             (R.string.question,
             (correctAnswers + 1),
              FLAGS_IN_QUIZ);

给出了getResources的静态与非静态错误。 我只是选择了一种不太适合的格式,但适合。

我还在onCreateView assets成为全局static变量,仅可以分配一次。

因此,教科书并非总能正确地做到这一点,因为这样做会使文本的水平大大超出预期的受众。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM