十六进制转字节会有编码影响吗

十六进制转字节会有编码影响吗,第1张

Emoji从最早开始到现在,比较通用的是两种编码方案,分别是Softbank和Unicode,android版微信早期也是使用Softbank编码,然后客户端根据表情对应的Softbank编码使用SpannableString在TextView, EditText中显示成对应的表情,此时Emoji表情的集合还不是很多,微信只打包进去了大概400多个左右,在早期可以满足大部分Emoji表情的显示需求

但是,随着Unicode 60以及Unicode 70的发布,越来越Emoji表情被加入到这个标准当中,iOS系统自行扩展OpenType标准,通过Apple Color Emojittf这个字体来讲Emoji表情直接显示出来(OSX下也有这个字体,在/System/Library/Fonts/Apple Color Emojittf),当时国外也有对这个问题进行过讨论:Color bitmapfonts thanks to Apple! ,但是,由于新加进来的表情都没有对应的Softbank编码,无法转码成Softbank,并且客户端在打包的时候只放进了400多个Emoji表情,所以在显示的时候,只能转换成""来显示

后来,随着越来越多表情不能显示,我们这边曾经尝试过直接在客户端使用unicode编码,并尝试过一次对外的灰度,在灰度的过程中,我们发现了一些crash,占的总量还不低,crash的堆栈大概是这样的:

at androidtextSpannableStringInternalgetChars(SpannableStringInternaljava:102)

at androidtextTextUtilsgetChars(TextUtilsjava:105)

at androidtextLayoutprocessToSupportEmoji(Layoutjava:3747)

at androidtextLayoutsupportTabandEmoji(Layoutjava:3783)

at androidtextLayoutmeasureText2(Layoutjava:3141)

我们注意到了 processToSupportEmoji 这个方法,明显不是属于Android系统原有的方法,应该是某些rom自行更改出现的问题,google一下,果不其然,在某些MTK的rom中有这样的一段代码,是属于processToSupportEmoji中的:

int length = end - start +1;

char[] chs = TextUtilsobtain(length);

TextUtilsgetChars(text, start, end, chs, 0);

for (int i = start ; i < end; i++) {

char c = chs[end-start];

if (c >= 0xD800 && c <= 0xDFFF && i + 1 < length) {

char[] tmp = TextUtilsobtain(2);

TextUtilsgetChars(text, i, i+2, tmp, 0);

可以看出这段代码对数据越界的保护是错误的,很容易就crash,有兴趣可以看下这篇文章:Android程序自动退但是没有提示任何错误

发生这个crash的大部分都是23系统的手机,也有一部分是4x,sony的一些机器也有,估计是复用了同一份代码。

So,问题的答案到这里就很明显了,将部分表情替换成点点的原因主要是这样的:

1 大部分新表情都没有对应的unicode编码,而换了unicode编码,TextView/EditText直接显示在一些机器中就会遇到上面的crash

2 考虑到安装包的大小,目前也没有把太多表情直接打包进去的打算(从目前版本的OSX中提取出来的表情大概有800多个,全部直接打包进去的话,会给安装包增加1~2M的体积)

BTW,Google在44之后也自行扩展了OpenType标准,同时也添加了一套自己的小黄人Emoji表情,可以直接在Google输入法中输入

请检查你这个activity的permission,有没有加上以下的设置。

在AndroidManifestxml里面添加。

<uses-permission android:name="androidpermissionBROADCAST_STICKY" />

<uses-permission android:name="androidpermissionCALL_PHONE" />

<uses-permission android:name="androidpermissionCALL_PRIVILEGED" />

<uses-permission android:name="androidpermissionINTERNET" />

<uses-permission android:name="androidpermissionPROCESS_OUTGOING_CALLS" />

另外帮你贴下android自带拨号程序的核心部分,请自己参照下吧~~

public class OutgoingCallBroadcaster extends Activity {

private static final String PERMISSION = androidManifestpermissionPROCESS_OUTGOING_CALLS;

private static final String TAG = "OutgoingCallBroadcaster";

private static final boolean LOGV = true;//ConfigLOGV;

public static final String EXTRA_ALREADY_CALLED = "androidphoneextraALREADY_CALLED";

public static final String EXTRA_ORIGINAL_URI = "androidphoneextraORIGINAL_URI";

private Phone mPhone;

@Override

protected void onCreate(Bundle icicle) {

superonCreate(icicle);

mPhone = PhoneAppgetInstance()phone;

Intent intent = getIntent();

if (LOGV) Logv(TAG, "onCreate: Got intent " + intent + "");

String action = intentgetAction();

String number = PhoneNumberUtilsgetNumberFromIntent(intent, this);

if (number != null) {

number = PhoneNumberUtilsstripSeparators(number);

}

final boolean emergencyNumber =

(number != null) && PhoneNumberUtilsisEmergencyNumber(number);

boolean callNow;

if (getClass()getName()equals(intentgetComponent()getClassName())) {

// If we were launched directly from the OutgoingCallBroadcaster,

// not one of its more privileged aliases, then make sure that

// only the non-privileged actions are allowed

if (!IntentACTION_CALLequals(intentgetAction())) {

Logw(TAG, "Attempt to deliver non-CALL action; forcing to CALL");

intentsetAction(IntentACTION_CALL);

}

}

/ Change CALL_PRIVILEGED into CALL or CALL_EMERGENCY as needed /

if (IntentACTION_CALL_PRIVILEGEDequals(action)) {

action = emergencyNumber

IntentACTION_CALL_EMERGENCY

: IntentACTION_CALL;

intentsetAction(action);

}

if (IntentACTION_CALLequals(action)) {

if (emergencyNumber) {

finish();

return;

}

callNow = false;

} else if (IntentACTION_CALL_EMERGENCYequals(action)) {

if (!emergencyNumber) {

finish();

return;

}

callNow = true;

} else {

finish();

return;

}

// Make sure the screen is turned on This is probably the right

// thing to do, and more importantly it works around an issue in the

// activity manager where we will not launch activities consistently

// when the screen is off (since it is trying to keep them paused

// and has issues)

//

// Also, this ensures the device stays awake while doing the following

// broadcast; technically we should be holding a wake lock here

// as well

PhoneAppgetInstance()wakeUpScreen();

/ If number is null, we're probably trying to call a non-existent voicemail number or

something else fishy Whatever the problem, there's no number, so there's no point

in allowing apps to modify the number /

if (number == null || TextUtilsisEmpty(number)) callNow = true;

if (callNow) {

intentsetClass(this, InCallScreenclass);

startActivity(intent);

}

Intent broadcastIntent = new Intent(IntentACTION_NEW_OUTGOING_CALL);

if (number != null) broadcastIntentputExtra(IntentEXTRA_PHONE_NUMBER, number);

broadcastIntentputExtra(EXTRA_ALREADY_CALLED, callNow);

broadcastIntentputExtra(EXTRA_ORIGINAL_URI, intentgetData()toString());

broadcastIntentputExtra(EXTRA_INTENT_FROM_BT_HANDSFREE,

intentgetBooleanExtra(OutgoingCallBroadcasterEXTRA_INTENT_FROM_BT_HANDSFREE, false));

if (LOGV) Logv(TAG, "Broadcasting intent " + broadcastIntent + "");

sendOrderedBroadcast(broadcastIntent, PERMISSION, null, null,

ActivityRESULT_OK, number, null);

finish();

}

}

以上就是关于十六进制转字节会有编码影响吗全部的内容,包括:十六进制转字节会有编码影响吗、Android利用ListView做一个电话簿app,求大佬帮助,尽量详细、Android 微信对 emoji 的支持是不是很差为何这样设计等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/10099677.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存