안드로이드에서 무시할 수 있는 오류 및 개발 팁 모음[지속적인 업데이트]
본고는 주로 안드로이드 개발에서 주의하지 않았을 수도 있지만 붕괴를 초래할 수도 있다는 문제와 실용적인 개발 팁을 모은 것으로 지속적으로 업데이트될 것이다.
(一)오편
1. ClickSpan으로 인한 긴 누르기 붕괴(TextView에서 ClickSpan을 사용한 후 이 TextView를 길게 누르면 붕괴될 수 있음)
예시 코드는 다음과 같다.
TextView content = (TextView)findViewById(R.id.tv_content);
content.setTextColor(content.getResources().getColor(R.color.util_lib_white));
String colorStr = item.getUserInfo().getNickname();
SpannableString colorString = StringUtil.colorString(colorStr + " : ",
content.getResources().getColor(R.color.util_lib_color_green_7bde4e));
colorString.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
@Override
public void onClick(View view) {
LogUtil.e();
if (null != mChatUserClickListener &&
!TextUtils.equals(item.getUserInfo().getUuid(), UserConfig.getUid())){
mChatUserClickListener.onChatUserClick(item.getUserInfo().getUuid());
}
}
}, 0, colorString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
content.setMovementMethod(LinkMovementMethod.getInstance());
content.setText(colorString);
content.append(item.getText());
이 코드는 TextView를 길게 누르면 충돌을 일으킬 수 있으며 충돌하는 log는 다음과 같습니다.
java.lang.NullPointerException
Attempt to invoke virtual method 'int android.widget.Editor$SelectionModifierCursorController.getMinTouchOffset()' on a null object reference
android.widget.Editor.touchPositionIsInSelection(Editor.java:832)
android.widget.Editor.performLongClickMz(Editor.java:5268)
android.widget.TextView.performLongClick(TextView.java:9126)
android.view.View$CheckForLongPress.run(View.java:20357)
android.os.Handler.handleCallback(Handler.java:815)
android.os.Handler.dispatchMessage(Handler.java:104)
android.os.Looper.loop(Looper.java:194)
android.app.ActivityThread.main(ActivityThread.java:5803)
java.lang.reflect.Method.invoke(Native Method)
java.lang.reflect.Method.invoke(Method.java:372)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1009)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:804)
이 충돌이 발생한 것은 콘텐츠를 호출했기 때문입니다.setMovementMethod(LinkMovementMethod.getInstance()); 이 방법은 다음과 같이 내부적으로 구현됩니다.
public final void setMovementMethod(MovementMethod movement) {
if (mMovement != movement) {
mMovement = movement;
if (movement != null && !(mText instanceof Spannable)) {
setText(mText);
}
fixFocusableAndClickableSettings();
// SelectionModifierCursorController depends on textCanBeSelected, which depends on
// mMovement
if (mEditor != null) mEditor.prepareCursorControllers();
}
}
private void fixFocusableAndClickableSettings() {
if (mMovement != null || (mEditor != null && mEditor.mKeyListener != null)) {
setFocusable(true);
setClickable(true);
setLongClickable(true);
} else {
setFocusable(false);
setClickable(false);
setLongClickable(false);
}
}
setLongClickable(true)로 호출되는 것을 볼 수 있습니다.방법은 이때 길게 누르면 위log와 같은 붕괴가 발생하고 해결 방안은 한눈에 알 수 있다. 두 가지가 있는데 모두 길게 누르는 이벤트를 차단하는 것이다. (1) TextView를 호출한다.setLongClickable(false); 이벤트를 길게 누르는 것을 사용하지 않기 (2) TextView를 호출합니다.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { return true; } }); 소비가 줄어들면 사건에 따라 됩니다.
2. Android Studio 디버깅, App 자동 재부팅, 콘솔에서 log 캡처 실패
이것은 AS가 충돌할 때 자동으로 현재 응용 프로그램을 다시 시작하고 상황logcat에서 발생하기 때문에 현재의 해결 방안은 대체로 다음과 같다.
Show only selected application No Filters log【 】;
//todo: 더 추가...
=========화려한 분할선 ==========
(2) 기교편
1. Api 23 후 HttpClient 빨리 오픈
module build.gradle :
android{
useLibrary 'org.apache.http.legacy'
}
2. RecycleView의 item에서 클릭한 selector(5.0 이전) 또는 파문 효과(5.0 및 그 후)
item View :
android:foreground="?android:attr/selectableItemBackground"
3. aar 의존 패키지 참조
(1) module build.gradle [ android{} ]:
repositories{
flatDir{
dirs "libs"
}
}
(2) dependecies :
compile(name:'aarmodulename', ext:'aar')
4. 문자열 [CharSequence] 등급 결정
TextUtils.equals(stringA, stringB);
내부 구현 및 주석을 보십시오.
/**
* Returns true if a and b are equal, including if they are both null.
* Note: In platform versions 1.1 and earlier, this method only worked well if
* both the arguments were instances of String.
* @param a first CharSequence to check
* @param b second CharSequence to check
* @return true if a and b are equal
*/
public static boolean equals(CharSequence a, CharSequence b) {
if (a == b) return true;
int length;
if (a != null && b != null && (length = a.length()) == b.length()) {
if (a instanceof String && b instanceof String) {
return a.equals(b);
} else {
for (int i = 0; i < length; i++) {
if (a.charAt(i) != b.charAt(i)) return false;
}
return true;
}
}
ps:TextUtils는 괜찮은 시스템 도구 종류로 실용적인 방법이 많기 때문에 한 번 훑어보는 것을 권장합니다.
5. String.format() 사용
String.format("%s --- userId : %s --- publishUri : %s", roomInfo.getUuid(), roomInfo.getUserId(), roomInfo.getPublishUri();
주로 다음과 같은 용도로 사용됩니다.
roomInfo.getUuid() + " --- userId : " + roomInfo.getUserId() + " --- " + "publishUri : " + roomInfo.getPublishUri()
이와 같은 문자열의 결합은 물론%s를 제외한 많은 자리 차지 문자, 예를 들어%d 등도 지원한다.
ps: 자세한 사용 설명은 사용자가 원하는 것을 얻을 수 있으므로 사용법을 설명할 필요가 없습니다.
6.
//todo 추가...
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.