You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Realm读取UTF-8编码尼泊尔语(天城文)字符时出现�乱码问题求助

解决Realm存储尼泊尔语(天城文)出现�乱码的方案

我之前处理过类似的非ASCII字符存储乱码问题,结合你用到的Realm、Gson和Retrofit技术栈,咱们一步步来排查解决:

1. 确保Retrofit/OkHttp强制使用UTF-8解析响应

乱码的常见根源是服务器返回的响应未明确指定UTF-8编码,而Retrofit默认会用ISO-8859-1解析,导致非ASCII字符被破坏。你可以通过OkHttp拦截器强制响应使用UTF-8:

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(chain -> {
        Response originalResponse = chain.proceed(chain.request());
        // 强制将响应体的媒体类型设置为UTF-8编码的JSON
        return originalResponse.newBuilder()
                .body(ResponseBody.create(
                        MediaType.parse("application/json; charset=utf-8"),
                        originalResponse.body().bytes()
                ))
                .build();
    })
    .build();

2. 配置Gson避免不必要的字符转义

Gson默认会对部分UTF-8字符做HTML转义,这可能导致存储到Realm前字符就被错误处理。调整Gson配置,禁用HTML转义并确保UTF-8字符完整保留:

Gson gson = new GsonBuilder()
    .disableHtmlEscaping() // 禁止转义UTF-8特殊字符
    .create();

// 把配置好的Gson传入Retrofit的转换器
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(BASE_URL)
    .client(client)
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build();

3. 验证Realm存储前的字符串正确性

在将字符串存入Realm前,先打印或校验字符串的编码状态,确认它是正确的UTF-8格式:

// 比如在Retrofit回调中拿到数据后
call.enqueue(new Callback<NepaliResponse>() {
    @Override
    public void onResponse(Call<NepaliResponse> call, Response<NepaliResponse> response) {
        if (response.isSuccessful() && response.body() != null) {
            String rawNepaliText = response.body().getNepaliText();
            // 打印原始字符串,确认在存储前没有乱码
            Log.d("Pre-Realm Text", rawNepaliText);
            // 可选:校验字符串是否可被UTF-8编码
            boolean canEncode = Charset.forName("UTF-8").newEncoder().canEncode(rawNepaliText);
            Log.d("UTF-8 Check", "Can encode: " + canEncode);

            // 存入Realm
            Realm realm = Realm.getDefaultInstance();
            realm.executeTransaction(r -> {
                NepaliData data = r.createObject(NepaliData.class);
                data.setNepaliText(rawNepaliText);
            });
            realm.close();
        }
    }

    @Override
    public void onFailure(Call<NepaliResponse> call, Throwable t) {
        // 错误处理逻辑
    }
});

4. 读取Realm数据时避免额外编码转换

读取Realm中的字符串时,直接使用原字符串,不要手动进行字节转码操作(比如new String(str.getBytes(), "UTF-8")这类多余操作会破坏编码):

Realm realm = Realm.getDefaultInstance();
NepaliData storedData = realm.where(NepaliData.class).findFirst();
if (storedData != null) {
    String retrievedText = storedData.getNepaliText();
    Log.d("Post-Realm Text", retrievedText);
    // 直接展示到UI或使用
    nepaliTextView.setText(retrievedText);
}
realm.close();

5. 额外排查点

  • 确认服务器返回的响应头Content-Type是否包含charset=utf-8,如果服务器能直接配置这个头,可以省去OkHttp拦截器的步骤
  • 检查UI展示时的字体是否支持尼泊尔语(天城文),不过�乱码通常是编码问题而非字体缺失,字体问题会显示方块而非�

内容的提问来源于stack exchange,提问作者Aaiam Litigoner

火山引擎 最新活动