|
|
|
|
|
|
|
|
|
|
|
|
// 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);
@Override
public void getDetail(long id, Callback<Goods> callback) {
Map<String, Object> params = new HashMap<>();
params.put("id", id);
HttpUtil.request("goods/detail", params, callback);
}
@Override
public void create(Goods goods, Callback<Goods> callback) {
Map<String, Object> params = new HashMap<>();
params.put("goods", goods);
HttpUtil.request("goods/create", params, callback);
}
@Override
public 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(Void> callback); Goods goods, 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