디디앱의 품질 최적화 프레임워크 Booster, 오픈!

5812 단어 android
하나.순서
앱이 일정한 규모에 도달할 때 품질 최적화를 고려해야 한다.몇몇 사소한 문제는 0.01% 촉발률에 불과한 것처럼 보이지만 DAU 천만이 넘는 제품에서 발생하면 심각하다.
디디라는 유니콘의 DAU는 이미 천만이 넘었기 때문에 자연히 독특한 최적화 방안이 있다.최근 디디는 Github에서 안드로이드 앱의 품질 최적화 도구인 Booster를 개발하여 동적 발견과 마운트 메커니즘을 통해 확장 가능한 능력을 제공하였다.모바일 응용의 품질 최적화 프레임워크와 같다.
최적화라고 하면 구체적으로 뭘 할 수 있는지도 모르는 것 같다.특성상 포괄적으로 볼 때 부스터는 성능 검사와 최적화, 가방 부피 다이어트, 코드 주입 등을 할 수 있다.
살짝 살펴보면 일시적으로 지원하는 최적화는 유한하지만 좋은 Booster는 매우 편리한 확장 능력을 제공하여 우리는 업무 상황에 따라 맞춤형 최적화를 할 수 있다.
부스터는 아직 최적화점이 적지만 오픈소스와 함께 후속 발전된 로드맵을 제시해 향후 기능은 점점 완벽해질 것으로 보인다.디디뉴 오픈소스의 부스터를 알아본다.
둘.Booster
2, 1. Booster란 무엇인가.
Booster는 모바일 애플리케이션을 위해 디자인된 간단하고 가볍고 기능이 강하며 확장 가능한 품질 최적화 도구 패키지로 동적 발견과 마운트 메커니즘을 통해 확장 가능한 능력을 제공한다.모바일 응용의 품질 최적화 프레임워크입니다.
Booster는 주로 Transformer와 Task로 구성됩니다.
Transformer는 바이트 코드를 스캔하거나 수정하는 데 사용되며, Task는 구축 중인 자원을 처리하는 데 사용됩니다.
Booster는 서로 다른 업무 장면에서의 최적화 수요를 만족시키기 위해 Transformer SPI와Variant Processor SPI 인터페이스를 제공하여 개발자가 맞춤형 제작을 할 수 있도록 한다.
Booster의 전체 프레임은 다음과 같습니다.
Booster는Gradle에 대한 몇 가지 이터레이션 요구 사항이 있습니다.
  • Gradle 4.1 이상 버전
  • Android Gradle 플러그인 3.0 이상
  • 2.2 Booster가 뭘 할 수 있을까?
    공식적인 개념을 한 번 읽어봤는데 Booster의 용도를 모르는 것 같다. 여기서 Booster가 이미 지원한 Transformer를 예로 들어 도대체 무엇을 할 수 있는지 설명한다.
    Toast는 우리가 일상적인 개발에서 자주 사용하는 힌트 정보의 구성 요소인데 안드로이드 7.0의 시스템에서는BadTokenException의 이상을 촉발할 수 있다.이 문제는 부스터로 해결할 수 있다.
    Toast가 BadToken Exception을 던지는 것은 디스플레이를 할 때 창의 Token이 효력을 상실한 것처럼 보일 수도 있고 Toast를 표시할 때 창이 이미 소각되었을 수도 있다.
    android.view.WindowManager$BadTokenException: 
        at android.view.ViewRootImpl.setView(ViewRootImpl.java)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java4)
        at android.widget.Toast$TN.handleShow(Toast.java)

    이 문제는 안드로이드 7.0에서만 발생했고 이후 버전에서는 이 문제를 해결하기 위해 직접 이 이상을 캐치해서 해결했다.다음은 Android 8.0에 대한 코드입니다.
    try {
        mWM.addView(mView, mParams);
        trySendAccessibilityEvent();
    } catch (WindowManager.BadTokenException e) {
        /* ignore */
    }

    비록 이 문제는 이미 몇 가지 해결 방안이 있지만, Booster는 우리에게 또 다른 선택을 주었다.
    Booster에 Transformers가 내장되어 있는데 그 중에서 booster-transform-bugfix-toast가 있는데 안드로이드 7.0에서 Toast가 초래한 시스템 오류를 복구하는 데 사용된다.
    ToastBugfixTransformer의 주요 소스는 다음과 같습니다.
    @AutoService(ClassTransformer::class)
    class ToastBugfixTransformer : ClassTransformer {
    
        override fun transform(context: TransformContext, klass: ClassNode): ClassNode {
            klass.methods.forEach { method ->
                method.instructions?.iterator()?.asIterable()?.filterIsInstance(MethodInsnNode::class.java)?.filter {
                    it.owner == TOAST && it.name == "show" && it.desc == "()V"
                }?.forEach {
                    it.owner = `TOAST'`
                    it.desc = "(L$TOAST;)V"
                    it.opcode = Opcodes.INVOKESTATIC
                }
            }
            return klass
        }
    }
    private const val TOAST = "android/widget/Toast"
    private const val `TOAST'` = "com/didiglobal/booster/$TOAST"

    그것은 시스템의 Toast를 다른 맞춤형 com으로 전달하는 것이다.didiglobal.booster.android.widget 가방에 있는 Toast가 해결합니다.
    public static void show(final android.widget.Toast toast) {
        if (Build.VERSION.SDK_INT == 25) {
            workaround(toast).show();
        } else {
            toast.show();
        }
    }
    
    private static android.widget.Toast workaround(final android.widget.Toast toast) {
        final Object tn = getFieldValue(toast, "mTN");
        if (null == tn) {
            Log.w(TAG, "Field mTN of " + toast + " is null");
            return toast;
        }
    
        final Object handler = getFieldValue(tn, "mHandler");
        if (handler instanceof Handler) {
            if (setFieldValue(handler, "mCallback", new CaughtCallback((Handler) handler))) {
                return toast;
            }
        }
    
        final Object show = getFieldValue(tn, "mShow");
        if (show instanceof Runnable) {
            if (setFieldValue(tn, "mShow", new CaughtRunnable((Runnable) show))) {
                return toast;
            }
        }
    
        Log.w(TAG, "Neither field mHandler nor mShow of " + tn + " is accessible");
        return toast;
    }

    API Level이 25가 아닐 경우 직접 호출Toast.show() 방법이 25일 경우 현재 Toast의 상황을 반사하여 판단하고 유효한 Toast 대상을 되돌려 다시 호출show()한다.
    여기서 Toast의 7.0 문제를 복원했습니다. 저희가 정상적으로 개발하는 과정에서 Toast의 사용을 전혀 걱정할 필요가 없고 품질 보증을 하는 사람과 업무를 하는 사람도 구분할 수 있습니다.
    2.3 Booster에 내장된 기능
    Booster가 기원을 시작했을 때 내부에 Transformer와Task가 내장되어 있었다. 앞에서 소개한 booster-transform-bugfix-toast가 그 중의 하나이다.
    내장형 Transformers
  • booster-transform-bugfix-toast: 7.0에서 Toast로 인한 시스템 오류를 복구합니다.
  • booster-transform-lint: 잠재적인 성능 문제를 검사합니다.
  • booster-transform-shrink:class 파일의 상수를 제거하는 데 사용합니다.
  • booster-transform-usage: 특정 API의 사용 상황을 스캔하는 데 사용됩니다.

  • 내장형 Tasks
  • Booster-task-artifact:artifact를 표시하는Task를 제공합니다.
  • Booster-task-dependency: 모든 의존 항목의 식별자와 파일 경로를 표시하는Task를 제공합니다.
  • Booster-task-permission: 모든 의존항에 사용되는 안드로이드를 표시할 수 있는 권한을 제공합니다.

  • 이러한 Booster가 제공하는Transformer와Task는 기능이 아직 제한되어 있고 지도적인 의미를 제공하여 원본을 통해 Booster의 사용을 알 수 있다.
    더 많은 아이디어를 가지고 Transformer와Task를 스스로 실현할 수 있습니다.
    발표된 Roadmap에서 성능 최적화, Lint, 자원 압축, 사용자 체험 등 다음 버전의 교체 계획을 제시했다.성능 최적화에서는 다중 스레드 사용, SP 사용, WebView 사전 로드를 맞춤형으로 최적화합니다.
    셋.소결 시간
    전체적으로 볼 때 Booster는 매우 좋은 성능 최적화 프레임워크로 성숙한 기술을 사용하여 이를 포장하여 우리가 사용하는 난이도를 낮춘다.큰 구덩이는 없으니 시도해 볼 필요가 있다.
    더 많은 콘텐츠는 Github에서 위키와 원본을 읽을 수 있으니 관심 있으면 스타를 주문하는 것을 잊지 마세요.
    Github:https://github.com/didi/booster
    본문이 당신에게 도움이 되었습니까?댓글, 좋아요, 리트윗이 가장 큰 지지입니다. 감사합니다!
    공중번호 백스테이지 회복 성장"
    "성장", 내가 준비한 학습 자료를 얻을 수 있고, 회답도 가능"
    함께 공부하고 진보하기;당신은 아직 회답을 할 수 있습니다"
    질문하다

    좋은 웹페이지 즐겨찾기