kotlin中针对api27getContext()为Nulla

作者: LeoYe168 | 来源:发表于2018-05-16 16:58 被阅读25次

    基础知识

    1. 在 Kotlin 中,其类型系统严格区分一个引用是否可以容纳null。也就是说,一个变量是否可空必须显示声明,对于可空变量,在访问其成员时必须做空处理,否则无法编译通过。

      var a: String = "abc"
      a = null // 编译错误
      
      var b: String? = "abc" //String? 表示该 String 类型变量可为空
      b = null // 编译通过
      
    2. 尽管当前kotlin在android项目开发中占比在逐步提高,但是大量开发还是Java代码。供应用层调用的framework代码也是java实现的,所以大量情景下是kotlin和java代码混合开发的。那当kotlin调用Java代码,Java代码是如何定义是否能容纳null呢?

      //不为空
        @NonNull
        public final Context requireContext() {
          Context context = getContext();
          if (context == null) {
              throw new IllegalStateException("Fragment " + this + " not attached to a context.");
          }
          return context;
      }
      
      //可为空
      @Nullable
      public Context getContext() {
          return mHost == null ? null : mHost.getContext();
      }
      

      函数参数是否容纳null判断也是同理用@Nullable和@NonNull标记

    问题

    1. 最近将compileSdkVersion、targetSdkVersion更新到27,然后收到了些编译错误,例如:context is now nullable(context?) instead of non-null, 特别在fragment中的getActivity(),fragmentManager等都有编译报错,扒了下代码查找报错的问题

      //报错 tpye mismatch required:context found:context?
       val viewDialog = AlertDialog.Builder(context)
      
      //context参数要求为  @NonNull
      public Builder(@NonNull Context context) {
              this(context, resolveDialogTheme(context, 0));
          }  
          
      

    //返回的context为 Nullable
    @Nullable
    public Context getContext() {
    return mHost == null ? null : mHost.getContext();
    }

    ```
    

    边缘报错的原因应该一目了然了。

    解决

    1. 直接告诉变压器context不可能为null,编译时候不去null检查。嗯,现在编译是不报错了,当然造成结果就是一旦为null直接挂了。而且既然API写的是Nullable,那就是存在为null的情况的

       builder = AlertDialog.Builder(context!!)
      
    2. 这个是在网上看到的解决方案,大概就是在basefragment中重写getContext()方法,跟1换汤不换药。

       override fun getContext(): Context {
          return super.getContext()!!
      

    }
    ```

    1. 其实APi27中新加了requireContext()方法,类似还有requireActivity(),requireHost()方法

         @NonNull
      public final Context requireContext() {
          Context context = getContext();
          if (context == null) {
              throw new IllegalStateException("Fragment " + this + " not attached to a context.");
          }
          return context;
      }
      

    }
    ```

    相关文章

      网友评论

        本文标题:kotlin中针对api27getContext()为Nulla

        本文链接:https://www.haomeiwen.com/subject/wnmfdftx.html