代码之家  ›  专栏  ›  技术社区  ›  Alexa289

为什么我的类中的init块在使用改型时未被触发?

  •  -1
  • Alexa289  · 技术社区  · 7 年前

    因此,我将从服务器获得如下JSON:

    {
        "success": "1",
        "data": [
            {
                "id": 1,
                "title": "1",
                "url": "5",
                "image": "resources/assets/images/banner_images/1548316546.mitra lakuin.png",
                "type": "category"
            },
            {
                "id": 2,
                "title": "2",
                "url": "5",
                "image": "resources/assets/images/banner_images/1548316605.mobile banner_-02 (1).png",
                "type": "category"
            },
            {
                "id": 4,
                "title": "4",
                "url": "5",
                "image": "resources/assets/images/banner_images/1547010221.gratis ongkir.png",
                "type": "category"
            },
            {
                "id": 5,
                "title": "Customer",
                "url": "5",
                "image": "resources/assets/images/banner_images/1548316659.customer service.png",
                "type": "category"
            }
        ],
        "message": "Banners are returned successfull."
    }
    

    我创建了2个类,以便将JSON转换为Banner对象。

    // 1.
    class BannerData(val message : String, val success : String, val data : List<Banner>) {}
    
    // 2.
    
    class Banner(id: Int, imageURL: String) {
    
        @SerializedName("image")
        var imageURL : String
        val id : Int
    
        init {
            Log.i("testX","triggered")
    
            this.id = id
    
            // The code below is used to add percent encoding to URL from server
    
            val unformattedFullPath = "${Endpoint.lakuin}/$imageURL"
            val formattedFullPath = URLConverterService.addingPercentEncoding(unformattedFullPath)
            this.imageURL = formattedFullPath
    
        }
    
    }
    

    改装界面如下所示:

        @GET("/app/getbanners")
        fun getBanners(): Call<BannerData>
    

    object RetrofitHandler {
    
        private val loggingInterceptor = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
    
        private val okHttpClient = OkHttpClient.Builder()
            .callTimeout(7,TimeUnit.SECONDS)
            .addInterceptor(loggingInterceptor)
            .build()
    
        private var retrofit = Retrofit.Builder()
            .baseUrl(Endpoint.lakuin) // default is set to lakuinAPI
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()
    
    
        fun <T> getInstance(APIType: Class<T>) : T {
            // baseURL should be change later, if there is more than one API, ex: GoogleMapAPI, LakuinAPI etc
            return retrofit.create(APIType)
        }
    
    }
    

    我的问题是。。。。。

    从上面的JSON可以看出,图像URL不完整,我想转换图像URL

    from:“resources/bla.png”

    成为: http://xxxx.com/resources/blablabla.png "

    Banner 班

    但是它似乎是应用程序中的init块 横幅 Log.i("testX","triggered") 从不在日志中显示

    我实际上可以创建Banner对象,但imageURL与JSON完全相同,这意味着init块永远不会被触发 enter image description here

    2 回复  |  直到 7 年前
        1
  •  6
  •   Maksim Novikov    7 年前

    如果您将“改装”设置为使用Gson库作为序列化/反序列化对象的库 addConverterFactory(GsonConverterFactory.create(gson)) , Gson 默认情况下,它不使用构造函数或init函数 instantiate an object and set its fields via reflection 我猜你的init块被跳过了,看看 要了解库是否可以配置为不跳过 init 作用

        2
  •  0
  •   Taras Parshenko    7 年前

    只需将url包装在单独的类中

    data class EndPointUrl(val url: String)
    

    创建一个类并扩展它 JsonDeserializer 和 JsonSerializer EndPointUrl 反之亦然

    class EndPointUrlSerializer : JsonDeserializer<EndPointUrl>, JsonSerializer<EndPointUrl> {
    
        @Throws(JsonParseException::class)
        override fun deserialize(
                json: JsonElement,
                type: Type,
                context: JsonDeserializationContext
        ) = EndPointUrl("${Endpoint.lakuin}/${json.asString}")
    
        override fun serialize(
                src: EndPointUrl,
                type: Type,
                context: JsonSerializationContext
        ) = JsonPrimitive(src.url)
    }
    

    在gson对象中注册序列化程序:

    val gson = GsonBuilder()
                     .registerTypeAdapter(EndPointUrl::class.java, EndPointUrlSerializer())
                     .create()
    

    在改装中使用此gson对象:

    val retrofit = Retrofit.Builder()
                       .baseUrl(BASE_URL)
                       .addConverterFactory(GsonConverterFactory.create(gson))
                       .build()
    

    现在你可以把 端点URL 对于您的响应对象:

    data class Banner(id: Int, imageURL: EndPointUrl)