Android scheme 점프 의 디자인 과 구현 에 대한 상세 한 설명
App 이 성장 함 에 따라 우 리 는 다음 과 같은 수 요 를 만 날 수 밖 에 없다.
QMUISchemeHandler
의 디자인 과 구현 을 분석 해 보 겠 습 니 다.scheme 의 형식 은 대략 이 렇 습 니 다.
schemeName://action?param1=value1¶m2=value2
예 를 들 면:
qmui://home?tab=2
기술적 인 측면 에서 볼 때 scheme 의 도약 을 실현 하 는 것 은 결코 어 려 운 일이 아니다.바로 다음 두 단계 이다.
if(action=="action1"){
doAction1(params)
}else if(action=="action2"){
doAction2(params)
}else {
...
}
새로운 scheme 이 추 가 될 때마다 if 를 추가 합 니 다.따라서 우 리 는 부지런히 생각 하고 재 구성 하 며 가능 한 한 빨리 좋 은 틀 을 설계 함으로써 자신의 두 손 을 해방 시 켜 야 한다.if else 와 같은 재 구성 에 있어 서 하나의 기본 적 인 방식 은 표 법 으로 모든 조건 과 실행 할 행 위 를 하나의 map 에 두 고 사용 할 때 이 map 를 조회 하여 실행 할 행 위 를 얻 는 것 이다.그리고 우 리 는 주 해 를 통 해 코드 생 성 방식 으로 이 맵 을 구축 하여 코드 의 작 성 량 을 줄 일 수 있 습 니 다.그 밖 에 우 리 는 각종 기능 적 수 요 를 고려 해 야 한다.
모든 라 이브 러 리 의 개발 은 업무 사용 자 를 안심 시 키 기 위해 라 이브 러 리 의 기능 이 충분 하고 사용 의 편리 성 을 확보 해 야 한다.QMUI Scheme 은 대외 적 으로 주로
QMUISchemeHandler
이라는 입구 류 와ActivityScheme
와FragmentScheme
두 개의 주해 이다.QMUISchemeHandler
QMUISchemeHandler
Builder 모드 를 통 해 실례 화:
// schemeName
val instance = QMUISchemeHandler.Builder("qmui://")
// scheme
.blockSameSchemeTimeout(1000)
// scheme decode
.addInterpolator(new QMUISchemeParamValueDecoder())
.addInterpolator(...)
// fragment factory
.defaultFragmentFactory(...)
// activity factory
.defaultIntentFactory(...)
// scheme
.defaultSchemeMatcher(...)
.build();
if(!instance.handle("qmui://xxx")){
// scheme handle, ?
}
대부분의 장면QMUISchemeHandler
은 단일 모델 을 사용 하면 된다.여러 개의 차단 기 를 설정 하고 fragment,activity 의 기본 인 스 턴 스 화학 공장,그리고 기본 적 인 일치 기 를 설정 할 수 있 습 니 다.인 스 턴 스 공장 과 매 칭 기 는 모두 기본 적 인 실현 을 제공 하고 대부분 장면 은 호출 자의 관심 을 필요 로 하지 않 습 니 다.또한 전역 기본 값 만 설정 하고 scheme 주석 층 에 도착 하면 모든 scheme 에 다른 값 을 지정 하여 사용자 정의 수 요 를 만족 시 킬 수 있 습 니 다.Activity Scheme 과 Fragment Scheme 주해
이 두 주 해 는 매우 비슷 하지만,Fragment 는 독립 되 었 기 때문에 더 많은 설정 항목 이 있 기 때문이다.
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface ActivityScheme {
// scheme action
String name();
// , action scheme , "type=4" , "type"
String[] required() default {};
// scheme , , ActivitySchemeRefreshable
boolean useRefreshIfCurrentMatched() default false;
// scheme , QMUISchemeMatcher
Class<?> customMatcher() default void.class;
// Activity , QMUISchemeIntentFactory
Class<?> customFactory() default void.class;
// , int/bool/long/float/double , string
String[] keysWithIntValue() default {};
String[] keysWithBoolValue() default {};
String[] keysWithLongValue() default {};
String[] keysWithFloatValue() default {};
String[] keysWithDoubleValue() default {};
}
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface FragmentScheme {
// ActivityScheme
String name();
String[] required() default {};
Class<?> customMatcher() default void.class;
String[] keysWithIntValue() default {};
String[] keysWithBoolValue() default {};
String[] keysWithLongValue() default {};
String[] keysWithFloatValue() default {};
String[] keysWithDoubleValue() default {};
// ActivityScheme, UI FragmentSchemeRefreshable
boolean useRefreshIfCurrentMatched() default false;
// ActivityScheme, QMUISchemeFragmentFactory
Class<?> customFactory() default void.class;
// Fragment activity , activity , activities activity
Class<?>[] activities();
// Activity
boolean forceNewActivity() default false;
// scheme Activity
String forceNewActivityKey() default "";
}
앞에서 열거 한 여러 가지 수 요 는 모두 SchemeHandler 와 두 개의 scheme 에서 나타 난 것 을 알 수 있다.쓰다
업무 사용자 에 대해 우 리 는
Activity
또는Fragment
에 주 해 를 붙 여야 한다.QMUISchemeHandler
기본 값 은 인 자 를 분석 하여Activity
intent 나Fragment
의 arguments 에 넣 습 니 다.따라서 우 리 는onCreate
에서 우리 가 관심 을 가 지 는 값 을 꺼 낼 수 있 습 니 다.
@ActivityScheme(name="activity1")
class Activity1: QMUIActivity{
override fun onCreate(...){
...
if(isStartedByScheme()){
// intent extra
val param1 = getIntent().getStringExtra(paramName)
}
}
}
@FragmentScheme(name="activity1", activities = {QDMainActivity.class})
class Fragment1: QMUIFragment{
override fun onCreate(...){
...
if(isStartedByScheme()){
// arguments
val param1 = getArguments().getString(paramName)
}
}
}
이러한 전송 방법 은 안 드 로 이 드 공식 디자인 의 방법 에 매우 부합 되 는데 이것 도Fragment
무 참 구조 기의 사용 방식 을 따라 야 한다.WebView 에 대해 서 는 재 작성
WebViewClient#shouldOverrideUrlLoading
을 통 해 scheme 점프 를 처리 할 수 있 습 니 다.
class MyWebViewClient: WebViewClient{
override fun shouldOverrideUrlLoading(view: WebView, url: String){
if(schemeHandler.handle(url)){
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest){
if(schemeHandler.handle(request.getUrl().toString())){
return true;
}
return super.shouldOverrideUrlLoading(view, request);
}
}
이루어지다QMUISchemeHandler
코드 생 성 방식 으로 컴 파일 기간 에 하나의SchemeMapImpl
류 를 생 성하 여SchemeMap
류 를 실현 했다.
public interface SchemeMap {
// action SchemeItem
SchemeItem findScheme(QMUISchemeHandler handler, String schemeAction, Map<String, String> params);
// schemeAction
boolean exists(QMUISchemeHandler handler, String schemeAction);
}
각 scheme 의 주 해 는 하나SchemeItem
에 대응 합 니 다.ActivityScheme
대응 실례 화 1 개ActivitySchemeItem
류 를 맵 에 추가FragmentScheme
대응 실례 화 1 개FragmentSchemeItem
류 를 맵 에 추가SchemeProcessor
을 통 해 생 성 된SchemeMapImpl
은 대략 다음 과 같다.
public class SchemeMapImpl implements SchemeMap {
private Map<String, List<SchemeItem>> mSchemeMap;
public SchemeMapImpl() {
mSchemeMap = new HashMap<>();
List<SchemeItem> elements;
ArrayMap<String, String> required = null;
elements = new ArrayList<>();
required =null;
elements.add(new FragmentSchemeItem(QDSliderFragment.class,false,new Class[]{QDMainActivity.class},null,false,"",required,null,null,null,null,null,SliderSchemeMatcher.class));
mSchemeMap.put("slider", elements);
elements = new ArrayList<>();
required = new ArrayMap<>();
required.put("aa", null);
required.put("bb", "3");
elements.add(new ActivitySchemeItem(ArchTestActivity.class,true,null,required,null,new String[]{"aa"},null,null,null,null));
mSchemeMap.put("arch", elements);
}
@Override
public SchemeItem findScheme(QMUISchemeHandler arg0, String arg1, Map<String, String> arg2) {
List<SchemeItem> list = mSchemeMap.get(arg1);
if(list == null || list.isEmpty()) {
return null;
}
for (int i = 0; i < list.size(); i++) {
SchemeItem item = list.get(i);
if(item.match(arg0, arg2)) {
return item;
}
}
return null;
}
@Override
public boolean exists(QMUISchemeHandler arg0, String arg1) {
return mSchemeMap.containsKey(arg1);
}
}
전체적인 디자인 과 실현 방향 은 바로 이렇다.나머지 는 각종 인 코딩 디 테 일이 다.관심 있 는 것 은QMUISchemeHandler#handle()
을 통 해 추적 하거나SchemeProcessor
코드 생 성 을 어떻게 하 는 지 볼 수 있다.이 기능 은 보기 에는 간단 해 보이 지만 사실은 Builder 모델,책임 체인 모델,공장 방법 등 디자인 모델 의 운용 도 포함 하고 SchemeMatcher,SchemeItem 등 대상 을 대상 으로 하 는 인터페이스,계승,다 형 등에 대한 운용 도 포함한다.읽 어 보 세 요.당신 에 게 깨 우 침 이 있 을 지도 모 릅 니 다.당신 도 잠재 적 인 bug 를 발견 할 수 있 을 지도 모 릅 니 다.총결산
안 드 로 이 드 scheme 점프 의 디자인 과 실현 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 안 드 로 이 드 scheme 점프 의 디자인 과 실현 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.