|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 0. 初始化Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com/") .build();
// 1. 声明服务接口public interface GitHubService { Call<List<Repo>> listRepos( String user);}
// 2. 通过Retrofit获取服务接口实例GitHubService service = retrofit.create(GitHubService.class);
// 3. 业务层调用Call<List<Repo>> repos = service.listRepos("octocat");
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://xxx.xxxxxx.xxx").client(new OkHttpClient.Builder().addInterceptor(new Interceptor() {public Response intercept(@NonNull Chain chain) throws IOException {// 添加统一请求头Request newRequest = chain.request().newBuilder().addHeader("Authorization", "Bearer " + token).build();return chain.proceed(newRequest);}}).build()).build();
Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);
Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/main/docs/static/logo.png");SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);draweeView.setImageURI(uri);
Glide.with(fragment) .load(myUrl) .into(imageView);
private static final Handler UI_HANDLER = new Handler(Looper.getMainLooper());
private void doTask() throws Throwable { Thread.sleep(3000); UI_HANDLER.post(new Runnable() { public void run() { refreshUI(); } });}
private final Handler UI_HANDLER = new Handler(Looper.getMainLooper()) { public void handleMessage(@NonNull Message msg) { if (msg.what == MSG_REFRESH_UI) { refreshUI(); } }};
private void doTask() throws Throwable { Thread.sleep(3000); UI_HANDLER.sendEmptyMessage(MSG_REFRESH_UI);}
public class MainActivity extends Activity { // ...
private void doTask() throws Throwable { Thread.sleep(3000); runOnUiThread(new Runnable() { public void run() { refreshUI(); } }); }}
private View view;
private void doTask() throws Throwable { Thread.sleep(3000); view.post(new Runnable() { public void run() { refreshUI(); } });}
private void startTask() { new Thread() { public void run() { doTask(); } }.start();}
private final Executor executor = Executors.newFixedThreadPool(10);
private void startTask() { executor.execute(new Runnable() { public void run() { doTask(); } });}
private void startTask() { new AsyncTask<Void, Void, Void>() { protected Void doInBackground(Void... voids) { doTask(); return null; } }.execute();}
val one = async { doSomethingUsefulOne() }val two = async { doSomethingUsefulTwo() }println("The answer is ${one.await() + two.await()}")
Future<String> fetchUserOrder() => Future.delayed(const Duration(seconds: 2), () => 'Large Latte');
Future<String> createOrderMessage() async { var order = await fetchUserOrder(); return 'Your order is: $order';}
function resolveAfter2Seconds(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 2000); });}
async function f1() { var x = await resolveAfter2Seconds(10); console.log(x); // 10}f1();
source .operator1() .operator2() .operator3() .subscribe(consumer)
{ "type": "toast", "content": "您好,欢迎来到XXX", "gravity": "<这里填写toast要展示的位置, 可选项为(center|top|bottom), 默认值为center>"}
{ "type": "dialog", "title": "提示", "message": "确定退出当前页面吗?", "confirmText": "确定", "cancelText": "取消", "confirmAction": { "type": "toast", "content": "您点击了确定" }}
{ "type": "finish"}
{ "type": "route", "url": "https://www.xxx.com/goods/detail?id=xxx"}
{ "type": "request", "url": "https://www.xxx.com/goods/detail", "method": "post", "params": { "id": "xxx" }, "response": { "successAction": { "type": "toast", "content": "当前商品的价格为${response.data.priceDesc}元" }, "errorAction": { "type": "dialog", "title": "提示", "message": "查询失败, 即将退出当前页面", "confirmText": "确定", "confirmAction": { "type": "finish" } } }}
private static Action getClickActionIfExists(String page, String event) { // 根据当前页面和事件确定动作标识 String actionId = String.format("hook/click/%s/%s", page, event); // 解析动态配置中, 是否有需要下发的Action String value = DynamicConfig.getValue(actionId, null); if (TextUtils.isEmpty(value)) { return null; } try { // 将下发Action解析为结构化数据 return JSON.parseObject(value, Action.class); } catch (JSONException ignored) { // 格式错误时不做处理 (供参考) } return null;}
/** * 包装点击事件的处理逻辑 * * @param page 当前页面标识 * @param event 当前事件标识 * @param clickListener 点击事件的处理逻辑 */public static View.OnClickListener handleClick(String page, String event, View.OnClickListener clickListener) { // 这里返回一个OnClickListener对象, 降低上层业务方的理解成本和代码改动难度 return new View.OnClickListener() { public void onClick(View v) { // 取出当前事件的下发配置 Action action = getClickActionIfExists(page, event); if (action != null) { // 有配置, 则走配置逻辑 performAction(action); } else if (clickListener != null) { // 无配置, 则走默认处理逻辑 clickListener.onClick(v); } } };}
// 之前addGoodsButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Router.open("https://www.xxx.com/goods/add"); }});
// 之后addGoodsButton.setOnClickListener(ActionManager.handleClick( "goods-manager", "add-goods", new View.OnClickListener() { public void onClick(View v) { Router.open("https://www.xxx.com/goods/add"); } }));
{ "hook/click/goods-manager/add-goods": { "type": "dialog", "title": "提示", "message": "由于XX原因,添加商品页面暂不可用", "confirmText": "确定", "confirmAction": { "type": "finish" } }}
public class GoodsListActivity extends Activity {
private final List<GoodsModel> dataList = new ArrayList<>(); private Adapter adapter;
protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_goods_list); RecyclerView recyclerView = findViewById(R.id.goods_recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); adapter = new Adapter(); recyclerView.setAdapter(adapter);
// 加载数据 dataList.addAll(...); adapter.notifyDataSetChanged(); }
private class Adapter extends RecyclerView.Adapter<ViewHolder> {
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.item_goods, parent, false); return new ViewHolder(view); }
public void onBindViewHolder(@NonNull ViewHolder holder, int position) { GoodsModel model = dataList.get(position); holder.title.setText(model.title); holder.price.setText(String.format("%.2f", model.price / 100f)); }
public int getItemCount() { return dataList.size(); } }
private static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView title; private final TextView price;
public ViewHolder(View itemView) { super(itemView); title = itemView.findViewById(R.id.item_title); price = itemView.findViewById(R.id.item_price); } }}
public class GoodsListActivity extends Activity {
private RecyclerViewHelper<GoodsModel> recyclerViewHelper;
protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_goods_list); RecyclerView recyclerView = findViewById(R.id.goods_recycler_view);
recyclerViewHelper = RecyclerViewHelper.of(recyclerView, R.layout.item_goods, (holder, model, position, itemCount) -> { TextView title = holder.getView(R.id.item_title); TextView price = holder.getView(R.id.item_price);
title.setText(model.title); price.setText(String.format("%.2f", model.price / 100f)); });
// 加载数据 recyclerViewHelper.addData(...); }}
Intent intent = new Intent(this, GoodsActivity.class);intent.putExtra("goodsId", model.goodsId);startActivity(intent);
<activity android:name=".GoodsActivity"> <intent-filter> <action android:name="https://www.xxx.com/goods/detail" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter></activity>
Intent intent = new Intent("https://www.xxx.com/goods/detail");intent.putExtra("goodsId", model.goodsId);startActivity(intent);
public class Router {
/** * 根据url跳转到目标页面 * * @param context 当前页面上下文 * @param url 目标页面url */ public static void open(Context context, String url) { // 解析为Uri对象 Uri uri = Uri.parse(url);
// 获取不带参数的url String urlWithoutParam = String.format( "%s://%s%s", uri.getScheme(), uri.getHost(), uri.getPath()); Intent intent = new Intent(urlWithoutParam);
// 解析url中的参数, 并通过Intent传递至下个页面 for (String paramKey : uri.getQueryParameterNames()) { String paramValue = uri.getQueryParameter(paramKey); intent.putExtra(paramKey, paramValue); }
// 执行跳转操作 context.startActivity(intent); }}
Router.open(this, "https://www.xxx.com/goods/detail?goodsId=" + model.goodsId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
目前托管Apache |
|
Dcloud |
|
|
|
|
|
|
|
// 构造线程池ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, keepAliveTimeUnit, workQueue, threadFactory, rejectedExecutionHandler);
// 提交子任务executor.execute(new Runnable() { public void run() { // 这里做子任务操作 }});
// 核心线程数int corePoolSize = 5;// 最大线程数int maximumPoolSize = 10;// 闲置线程保活时长int keepAliveTime = 1;// 保活时长单位TimeUnit keepAliveTimeUnit = TimeUnit.MINUTES;// 阻塞队列BlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<>(50);// 线程工厂ThreadFactory threadFactory = new ThreadFactory() { public Thread newThread(Runnable r) { return new Thread(r); }};// 任务溢出的处理策略RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
public class DataManager {
private UserHelper userHelper = new UserHelper(); private GoodsHelper goodsHelper = new GoodsHelper(); private OrderHelper orderHelper = new OrderHelper();}
public class DataManager {
private UserHelper userHelper; private GoodsHelper goodsHelper; private OrderHelper orderHelper;
public DataManager() { // 注入对象实例 (内部通过反射+注解实现) InjectManager.inject(this); }}
public class Manager { private void doSomething(String name) { // ... }}
try { Class<?> managerType = manager.getClass(); Method doSomethingMethod = managerType.getMethod("doSomething", String.class); doSomethingMethod.setAccessible(true); doSomethingMethod.invoke(manager, "<name参数>");} catch (Exception e) { e.printStackTrace();}
public class HttpUtil {
/** * 执行网络请求 * * @param relativePath url相对路径 * @param params 请求参数 * @param callback 回调函数 * @param <T> 响应结果类型 */ public static <T> void request(String relativePath, Map<String, Object> params, Callback<T> callback) { // 实现略.. }}
public interface GoodsApi {
/** * 分页查询商品列表 * * @param pageNum 页面索引 * @param pageSize 每页数据量 * @param callback 回调函数 */ void getPage(int pageNum, int pageSize, Callback<Page<Goods>> callback);}
public class GoodsApiImpl implements GoodsApi {
@Override public void getPage(int pageNum, int pageSize, Callback<Page<Goods>> callback) { Map<String, Object> params = new HashMap<>(); params.put("pageNum", pageNum); params.put("pageSize", pageSize); HttpUtil.request("goods/page", params, callback); }}
GoodsApi goodsApi = new GoodsApiImpl();goodsApi.getPage(1, 50, new Callback<Page<Goods>>() { public void onSuccess(Page<Goods> data) { // 成功回调 } public void onError(Error error) { // 失败回调 }});
/** * 查询商品详情 * * @param id 商品ID * @param callback 回调函数 */void getDetail(long id, Callback<Goods> callback);
@Overridepublic void getDetail(long id, Callback<Goods> callback) { Map<String, Object> params = new HashMap<>(); params.put("id", id); HttpUtil.request("goods/detail", params, callback);}
@Overridepublic void create(Goods goods, Callback<Goods> callback) { Map<String, Object> params = new HashMap<>(); params.put("goods", goods); HttpUtil.request("goods/create", params, callback);}
@Overridepublic void update(Goods goods, Callback<Void> callback) { Map<String, Object> params = new HashMap<>(); params.put("goods", goods); HttpUtil.request("goods/update", params, callback);}
Map<String, Object> params = new HashMap<>(); // 遍历当前方法参数, 执行以下语句 params.put("<参数名>", <参数值>); HttpUtil.request("<接口路径>", params, callback);
@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface Path {
/** * @return 接口路径 */ String value();}
@Target({ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)public @interface Param {
/** * @return 参数名称 */ String value();}
@SuppressWarnings("unchecked")public static <T> T getApi(Class<T> apiType) { return (T) Proxy.newProxyInstance(apiType.getClassLoader(), new Class[]{apiType}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 解析接口路径 String path = method.getAnnotation(Path.class).value();
// 解析接口参数 Map<String, Object> params = new HashMap<>(); Parameter[] parameters = method.getParameters(); // 注: 此处多偏移一位, 为了跳过最后一项callback参数 for (int i = 0; i < method.getParameterCount() - 1; i++) { Parameter parameter = parameters[i]; Param param = parameter.getAnnotation(Param.class); params.put(param.value(), args[i]); }
// 取最后一项参数为回调函数 Callback<?> callback = (Callback<?>) args[args.length - 1];
// 执行网络请求 HttpUtil.request(path, params, callback);
return null; } });}
public interface GoodsApi {
void getPage( int pageNum, int pageSize, Callback<Page<Goods>> callback);
void getDetail( long id, Callback<Goods> callback);
void create( Goods goods, Callback<Goods> callback);
void update( Goods goods, Callback<Void> callback);}
// 之前GoodsApi goodsApi = new GoodsApiImpl();
// 现在GoodsApi goodsApi = ApiProxy.getApi(GoodsApi.class);
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 略...
// A调用B button.setText("");
button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // B回调A } }); }}
public class GoodsCardView extends FrameLayout {
private final Button button; private OnFollowListener followListener;
public GoodsCardView(Context context, AttributeSet attrs) { super(context, attrs); // 略...
button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (followListener != null) { // C回调B followListener.onFollowClick(); } } }); }
public void setFollowText(String followText) { // C调用B button.setText(followText); }
public void setOnFollowClickListener(OnFollowListener followListener) { this.followListener = followListener; }}
public class MainActivity extends Activity {
private GoodsCardView goodsCard;
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 略...
// A调用C goodsCard.setFollowText("点击商品即可关注");
goodsCard.setOnFollowClickListener(new OnFollowListener() { public void onFollowClick() { // C回调A } }); }}
public class MainActivity extends Activity {
private RecyclerView recyclerView; private ImageView topIcon;
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 略...
topIcon.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // B回调C onTopIconClick(); } });
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { public void onScrollStateChanged(RecyclerView recyclerView, int newState) { // A回调C if (newState == RecyclerView.SCROLL_STATE_IDLE) { LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); onFirstItemVisibleChanged(layoutManager.findFirstVisibleItemPosition() == 0); } } }); }
private void onFirstItemVisibleChanged(boolean visible) { // C调用B topIcon.setVisibility(visible ? View.GONE : View.VISIBLE); }
private void onTopIconClick() { // C调用A recyclerView.scrollToPosition(0); // C调用B topIcon.setVisibility(View.GONE); }}
public class EventManager extends Observable<EventManager.OnEventListener> {
public interface OnEventListener { void onEvent(String action, Object... args); }
public void dispatch(String action, Object... args) { synchronized (mObservers) { for (OnEventListener observer : mObservers) { observer.onEvent(action, args); } } }}
public class AComponent {
public static final String ACTION_SOMETHING = "a_do_something";
private final EventManager eventManager;
public AComponent(EventManager eventManager) { this.eventManager = eventManager; }
public void sendMessage() { // A调用X eventManager.dispatch(ACTION_SOMETHING); }}
public class BComponent {
private final EventManager eventManager;
public BComponent(EventManager eventManager) { this.eventManager = eventManager; eventManager.registerObserver(new EventManager.OnEventListener() { public void onEvent(String action, Object... args) { if (AComponent.ACTION_SOMETHING.equals(action)) { // X分发B } } }); }}
public interface Callback { void onCall1();}
public class SDKManager {
private Callback callback;
public void setCallback(Callback callback) { this.callback = callback; }
private void doSomething1() { // 略... if (callback != null) { callback.onCall1(); } }}
SDKManager sdkManager = new SDKManager();sdkManager.setCallback(new Callback() { public void onCall1() { }});
public interface Callback { void onCall1();
void onCall2();}
sdkManager.setCallback(new Callback() { public void onCall1() { }});
public interface Callback2 { void onCall2();}
public class SDKManager { // 略..
private Callback2 callback2;
public void setCallback2(Callback2 callback2) { this.callback2 = callback2; }
private void doSomething2() { // 略... if (callback2 != null) { callback2.onCall2(); } }}
sdkManager.setCallback2(new Callback2() { public void onCall2() { }});
public interface Callback {}
public interface Callback1 extends Callback { void onCall1();
}
public interface Callback2 extends Callback { void onCall2();}
public class SDKManager {
private Callback callback;
public void setCallback(Callback callback) { this.callback = callback; }
private void doSomething1() { // 略... if ((callback instanceof Callback1)) { ((Callback1) callback).onCall1(); } }
private void doSomething2() { // 略... if ((callback instanceof Callback2)) { ((Callback2) callback).onCall2(); } }}
public class SimpleCallback implements Callback1, Callback2 {
public void onCall1() {
}
public void onCall2() {
}}
// 单接口方式设置回调sdkManager.setCallback(new Callback1() { public void onCall1() { // .. }});
// 组合接口方式设置回调interface CombineCallback extends Callback1, Callback2 {} sdkManager.setCallback(new CombineCallback() { public void onCall1() { // .. }
public void onCall2() { // ... }});
// 空实现类方式设置回调sdkManager.setCallback(new SimpleCallback() { public void onCall1() { // .. }
public void onCall2() { //.. }});
public interface Callback3 extends Callback { void onCall3();}
private void doSomething3() { // 略... if ((callback instanceof Callback3)) { ((Callback3) callback).onCall3(); }}
private void doSomething1() { // 略... if ((callback instanceof Callback1)) { ((Callback1) callback).onCall1(); }}
public class CallbackProxy implements Callback1, Callback2, Callback3 {
private Callback callback;
public void setCallback(Callback callback) { this.callback = callback; }
public void onCall1() { if (callback instanceof Callback1) { ((Callback1) callback).onCall1(); } }
public void onCall2() { if (callback instanceof Callback2) { ((Callback2) callback).onCall2(); } }
public void onCall3() { if (callback instanceof Callback3) { ((Callback3) callback).onCall3(); } }}
public class SDKManager {
private final CallbackProxy callbackProxy = new CallbackProxy();
public void setCallback(Callback callback) { callbackProxy.setCallback(callback); }
private void doSomething1() { // 略... callbackProxy.onCall1(); }
private void doSomething2() { // 略... callbackProxy.onCall2(); }
private void doSomething3() { // 略... callbackProxy.onCall3(); }}
《Android 中子线程真的不能更新 UI 吗?》:https://juejin.cn/post/6844904131136618510
《移动跨平台开发框架解析与选型》:https://segmentfault.com/a/1190000039122907