泰国对代孕的相关规定

█微信号█  13★710097773 █供卵试管婴儿██代孕选性别生男孩 ██试管包出生██代孕男孩██代孕包出生███代孕选性别██试管婴儿███代孕生男孩█████试管婴儿代孕生男孩███供卵试管婴儿代孕███

                });
    }

其实处理透明Activity阻挡操作可以采用取消所有事件变成无感页面的方法,但是还是觉得会影响activity堆栈没有采用这种方案

getwindow().addflags( windowmanager.layoutparams.flag_not_focusable
| windowmanager.layoutparams.flag_not_touch_modal 
| windowmanager.layoutparams.flag_not_touchable);

结果返回

这里我封装了一个库RxActivityResult去捕获onActivityResult,这样能保正流式调用

譬如拍照可以这样写,先定义一个接口

    public interface ImageCaptureService {

    @Action(MediaStore.ACTION_IMAGE_CAPTURE)
    Observable<Response> startImageCapture(); }

然后这样调用

public class MainActivity extends AppCompatActivity { @Service ImageCaptureService imageCaptureService; public void captureImage(){ imageCaptureService .startImageCapture() .subscribe(new Action1<Response>() { @Override public void call(Response response) { Intent data = response.getData(); int resultCode = response.getResultCode(); if (resultCode == RESULT_OK) { Bitmap imageBitmap = (Bitmap) data.getExtras().get("data"); } } }); } } }

是不是很简单,原理是这样的,通过封装一个RxResultHoldFragment去处理onActivityResult

private IActivityObservable buildActivityObservable() {

            T target = targetWeak.get();

            if (target instanceof FragmentActivity) { FragmentActivity activity = (FragmentActivity) target; android.support.v4.app.FragmentManager fragmentManager = activity.getSupportFragmentManager(); IActivityObservable activityObservable = RxResultHoldFragmentV4.getHoldFragment(fragmentManager); return activityObservable; } if (target instanceof Activity) { Activity activity = (Activity) target; FragmentManager fragmentManager = activity.getFragmentManager(); IActivityObservable activityObservable = RxResultHoldFragment.getHoldFragment(fragmentManager); return activityObservable; } if (target instanceof Context) { final Context context = (Context) target; IActivityObservable activityObservable = new RxResultHoldContext(context); return activityObservable; } if (target instanceof Fragment) { Fragment fragment = (Fragment) target; FragmentManager fragmentManager = fragment.getFragmentManager(); if (fragmentManager != null) { IActivityObservable activityObservable = RxResultHoldFragment.getHoldFragment(fragmentManager); return activityObservable; } } if (target instanceof android.support.v4.app.Fragment) { android.support.v4.app.Fragment fragment = (android.support.v4.app.Fragment) target; android.support.v4.app.FragmentManager fragmentManager = fragment.getFragmentManager(); if (fragmentManager != null) { IActivityObservable activityObservable = RxResultHoldFragmentV4.getHoldFragment(fragmentManager); return activityObservable; } } return new RxResultHoldEmpty(); }

动态拦截

拦截器是重中之重,有了拦截器可以做好多事情,可以说之所以要做页面路由,就是为了要实现拦截器。ARouter是用线程等待实现的,但是现在有Rxjava了,可以实现更优美的方式。
先来看一下我做的拦截器的效果.

@Intercept(path = "/second")
public class SecondInterceptor extends Interceptor { @Override public void intercept(final Call call) { Request request = call.getRequest(); final Intent intent = request.getIntent(); Context context = request.getContext(); StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("Intercept\n"); stringBuffer.append("URL: " + request.getUrl() + "\n"); AlertDialog.Builder builder = new AlertDialog.Builder(context,R.style.Theme_AppCompat_Dialog_Alert); builder.setTitle("Notice"); builder.setMessage(stringBuffer); builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { call.cancel(); } }); builder.setPositiveButton("ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { intent.putExtra("key1", "value3"); call.proceed(); } }); builder.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { call.cancel(); } }); builder.show(); } }

是不是很简单,参考了部分OkHttp的实现思路,加入Rxjava,实现异步拦截。

首先将请求转换成责任链模式RealCallChain,RealCallChain的call方法实际不会执行路由跳转,只有Interceptor里面调用了call.proceed或者call.cancel才会执行.

    private Observable<Request> buildRequest() {
        RealCallChain chain = new RealCallChain(interceptors, 0, request); chain.setTimeout(interceptTimeOut); chain.call(); return chain .getRequestObservable() .map(new Func1<Request, Request>() { @Override public Request call(Request request) { if (interceptors != null) { for (Interceptor interceptor : interceptors) { interceptor.onCall(request); } } return request; } }); }

接着处理异步的问题,这里用到了Rxjava的AsyncSubject和BehaviorSubject,

  1. AsyncSubject具有仅释放Observable释放的最后一个数据的特性,作为路由请求的发送器
  2. BehaviorSubject具有一开始就会释放最近释放的数据的特性,作为路由拦截器的发送器

具体实现看核心代码

    @Override
    public void proceed() { if (index >= interceptors.size()) { realCall(); return; } final Interceptor interceptor = interceptors.get(index); Observable .just(1) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { interceptor.intercept(RealCallChain.this); } }); interceptorSubject.onNext(interceptor); index = index + 1; }

方法调用

大部分路由库都是手动拼参数调用路由的,这里模仿了Retrofit接口式调用,受了LiteRouter的启发,不过Retrofit使用了动态代理,我使用的Apt没有性能损耗。

通过Apt生成每个接口的实际方法

譬如把SecondService接口

public interface SecondService {

    @Path("/second") @Activity(SecondActivity.class) void startSecondActivity(); }

生成

@Aspect
public final class SecondService$$Provider implements SecondService { public DeepLinkClient deepLinkClient; public SecondService$$Provider(DeepLinkClient deepLinkClient) { this.deepLinkClient= deepLinkClient; } @Override public void startSecondActivity() { Intent intent = new Intent(); intent.setData(Uri.parse("app://deeplink/second")); Request request = deepLinkClient.buildRequest(intent); if (request != null) { request.start(); } } @Around("execution(* okdeeplink.DeepLinkClient.build(..))") public Object aroundBuildMethod(ProceedingJoinPoint joinPoint) throws Throwable { DeepLinkClient target = (DeepLinkClient)joinPoint.getTarget(); if (joinPoint.getArgs() == null || joinPoint.getArgs().length != 1) { return joinPoint.proceed(); } Object arg = joinPoint.getArgs()[0]; if (arg instanceof Class) { Class buildClass = (Class) arg; if (buildClass.isAssignableFrom(getClass())) { return new SecondService$$Provider(target); } } return joinPoint.proceed(); } }

然后调用

SecondService secondServicenew = DeepLinkClient(target).build(SecondService.class);

SecondService就生成了。
为了调用方便,直接在Activity或者fragement写这段代码,sampleServive就自动生成了

  @Service
  SampleService sampleService;

但是如果用到MVP模式,不是在Activity里面调用路由,后面会支持在这些类里面自动注入SampleService,现在先用java代码build

参数获取

大部分路由库都是手动获取参数的,这样还要传入参数key比较麻烦,这里模仿了ARouter,不过我支持类型更全一些,支持Bundle支持的所有类型,而且不需要在Acitivty的onCreate调用获取代码。
通过Apt把这段代码

public class MainActivity extends AppCompatActivity { @Query("key") String key; }

生成

@Aspect
public class MainActivity$$Injector { @Around("execution(* okdeeplink.sample.MainActivity.onCreate(..))") public void onCreate(ProceedingJoinPoint joinPoint) throws Throwable { MainActivity target = (MainActivity)joinPoint.getTarget(); Bundle dataBundle = new Bundle(); Bundle saveBundle = (Bundle)joinPoint.getArgs()[0]; Bundle targetBundle = BundleCompact.getSupportBundle(target); if(targetBundle != null) { dataBundle.putAll(targetBundle); } if(saveBundle != null) { dataBundle.putAll(saveBundle); } try { target.key= BundleCompact.getValue(dataBundle,"key",String.class); } catch (Exception e) { e.printStackTrace(); } joinPoint.proceed(); } @After("execution(* okdeeplink.sample.MainActivity.onSaveInstanceState(..))") public void onSaveInstanceState(JoinPoint joinPoint) throws Throwable { MainActivity target = (MainActivity)joinPoint.getTarget(); Bundle saveBundle = (Bundle)joinPoint.getArgs()[0]; Intent intent = new Intent(); intent.putExtra("key",target.key); saveBundle.putAll(intent.getExtras()); } @Around("execution(* okdeeplink.sample.MainActivity.onNewIntent(..))") public void onNewIntent(ProceedingJoinPoint joinPoint) throws Throwable { MainActivity target = (MainActivity)joinPoint.getTarget(); Intent targetIntent = (Intent)joinPoint.getArgs()[0]; Bundle dataBundle = targetIntent.getExtras(); try { target.key= BundleCompact.getValue(dataBundle,"key",String.class); } catch (Exception e) { e.printStackTrace(); } joinPoint.proceed(); } }

Module接入不同App

这里是参考ARouter把path作为key对应activity,这样接入到其他app中,就自动替换了scheme码

DeepLinkClient.addAddress(new Address("/main", MainActivity.class));

安全

现在有好多人用脚本来打开App,然后干坏事,其实时可以用路由来屏蔽掉.

有三种方法供君选择,不同方法适合不同场景

签名屏蔽

就是把所有参数加密成一个数据作为sign参数,然后比对校验,但是这要求加密方法不变,要不然升级了以前的app就打不开了

adb打开屏蔽

在android5.1手机上,用adb打开的app它的mReferrer为空

 public boolean isStartByAdb(android.app.Activity activity){
        if (Build.VERSION.SDK_INT >= 22) { android.net.Uri uri = ActivityCompat.getReferrer(activity); return uri == null | TextUtils.isEmpty(uri.toString()) ; } return false; }

包名过滤

在Android 4.4手机上, 写了android:ssp的组件,只有特定应用可以打开

<activity
            android:name="okdeeplink.DeepLinkActivity"
            android:noHistory="true" android:theme="@android:style/Theme.Translucent.NoTitleBar"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:ssp="com.app.test" android:host="app" android:scheme="odl" /> </intent-filter> </activity>

这三种方法,比较适合的还是签名校验为主,adb过滤为副

如何解决路由造成的Activity堆栈错乱的问题

activity的launchMode使用不当会照成闪屏页面打开多次的问题,可以参考我这篇文章

未来展望

路由是一个基础模块,技术难度虽然不是很大,但是如果每个开发都重新踩一遍,性价比就比较低,我希望能把路由相关的所有链路都替你弄好,你可以留着时间去干其他更重要的事情,譬如陪陪家人,逗逗狗什么的。
接下来我会在这几个方面努力,把整条链路补全。

    • 做一个像Swagger的平台,支持一键导出所有路由、二维码打开路由

猜你喜欢

转载自www.cnblogs.com/dujiaCC/p/10940197.html
今日推荐