android: optimize java code

This commit is contained in:
pengfei.zhou 2021-07-22 17:30:44 +08:00 committed by osborn
parent 766154494b
commit fd6592f307
36 changed files with 171 additions and 199 deletions

View File

@ -27,6 +27,7 @@ import com.github.pengfeizhou.jscore.JSONBuilder;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@ -58,15 +59,20 @@ public class DoricContext {
private String extra;
private JSONObject initParams;
private IDoricDriver doricDriver;
private final Map<String, Map<String, ViewNode>> mHeadNodes = new HashMap<>();
private final Map<String, Map<String, ViewNode<?>>> mHeadNodes = new HashMap<>();
private final DoricPerformanceProfile performanceProfile;
public Collection<ViewNode> allHeadNodes(String type) {
return mHeadNodes.get(type).values();
public Collection<ViewNode<?>> allHeadNodes(String type) {
Map<String, ViewNode<?>> headNode = mHeadNodes.get(type);
if (headNode != null) {
return headNode.values();
} else {
return new ArrayList<>();
}
}
public void addHeadNode(String type, ViewNode viewNode) {
Map<String, ViewNode> map = mHeadNodes.get(type);
public void addHeadNode(String type, ViewNode<?> viewNode) {
Map<String, ViewNode<?>> map = mHeadNodes.get(type);
if (map != null) {
map.put(viewNode.getId(), viewNode);
} else {
@ -76,25 +82,25 @@ public class DoricContext {
}
}
public void removeHeadNode(String type, ViewNode viewNode) {
Map<String, ViewNode> map = mHeadNodes.get(type);
public void removeHeadNode(String type, ViewNode<?> viewNode) {
Map<String, ViewNode<?>> map = mHeadNodes.get(type);
if (map != null) {
map.remove(viewNode.getId());
}
}
public void clearHeadNodes(String type) {
Map<String, ViewNode> map = mHeadNodes.get(type);
Map<String, ViewNode<?>> map = mHeadNodes.get(type);
if (map != null) {
map.clear();
}
}
public ViewNode targetViewNode(String id) {
public ViewNode<?> targetViewNode(String id) {
if (id.equals(mRootNode.getId())) {
return mRootNode;
}
for (Map<String, ViewNode> map : mHeadNodes.values()) {
for (Map<String, ViewNode<?>> map : mHeadNodes.values()) {
if (map.containsKey(id)) {
return map.get(id);
}

View File

@ -47,7 +47,7 @@ import pub.doric.utils.DoricLog;
*/
public class DoricPanelFragment extends Fragment implements IDoricNavigator {
private DoricPanel doricPanel;
private Handler uiHandler = new Handler(Looper.getMainLooper());
private final Handler uiHandler = new Handler(Looper.getMainLooper());
private FrameLayout maskView;
@Override

View File

@ -69,7 +69,7 @@ import pub.doric.utils.DoricMetaInfo;
*/
public class DoricRegistry {
private final Map<String, DoricMetaInfo<DoricJavaPlugin>> pluginInfoMap = new HashMap<>();
private final Map<String, DoricMetaInfo<ViewNode>> nodeInfoMap = new HashMap<>();
private final Map<String, DoricMetaInfo<ViewNode<?>>> nodeInfoMap = new HashMap<>();
private final Set<IDoricMonitor> monitors = new HashSet<>();
@ -141,14 +141,14 @@ public class DoricRegistry {
return pluginInfoMap.get(name);
}
public void registerViewNode(Class<? extends ViewNode> pluginClass) {
DoricMetaInfo<ViewNode> doricMetaInfo = new DoricMetaInfo<>(pluginClass);
public void registerViewNode(Class<? extends ViewNode<?>> pluginClass) {
DoricMetaInfo<ViewNode<?>> doricMetaInfo = new DoricMetaInfo<>(pluginClass);
if (!TextUtils.isEmpty(doricMetaInfo.getName())) {
nodeInfoMap.put(doricMetaInfo.getName(), doricMetaInfo);
}
}
public DoricMetaInfo<ViewNode> acquireViewNodeInfo(String name) {
public DoricMetaInfo<ViewNode<?>> acquireViewNodeInfo(String name) {
return nodeInfoMap.get(name);
}

View File

@ -21,20 +21,28 @@ package pub.doric.async;
* @CreateDate: 2019-07-19
*/
public class AsyncResult<R> {
private static Object EMPTY = new Object();
private Object result = EMPTY;
private enum State {
IDLE,
RESULT,
ERROR,
}
private R result = null;
private Callback<R> callback = null;
private State state = State.IDLE;
private Throwable throwable = null;
public AsyncResult() {
}
public AsyncResult(R r) {
this.result = r;
this.state = State.RESULT;
}
public void setResult(R result) {
this.result = result;
this.state = State.RESULT;
if (this.callback != null) {
this.callback.onResult(result);
this.callback.onFinish();
@ -42,7 +50,8 @@ public class AsyncResult<R> {
}
public void setError(Throwable result) {
this.result = result;
this.throwable = result;
this.state = State.ERROR;
if (this.callback != null) {
this.callback.onError(result);
this.callback.onFinish();
@ -50,20 +59,20 @@ public class AsyncResult<R> {
}
public boolean hasResult() {
return result != EMPTY;
return this.state == State.RESULT;
}
public R getResult() {
return (R) result;
return result;
}
public void setCallback(Callback<R> callback) {
this.callback = callback;
if (result instanceof Throwable) {
this.callback.onError((Throwable) result);
if (this.state == State.ERROR) {
this.callback.onError(throwable);
this.callback.onFinish();
} else if (result != EMPTY) {
this.callback.onResult((R) result);
} else if (this.state == State.RESULT) {
this.callback.onResult(result);
this.callback.onFinish();
}
}

View File

@ -15,18 +15,14 @@
*/
package pub.doric.async;
/**
* @Description: com.github.penfeizhou.doric.async
* @Author: pengfei.zhou
* @CreateDate: 2019-07-18
*/
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* A super simple Future-like class that can safely notify another Thread when a value is ready.
* @Description: A super simple Future-like class that can safely notify another Thread when a value is ready.
* Does not support setting errors or canceling.
* @Author: pengfei.zhou
* @CreateDate: 2019-07-18
*/
public class SettableFuture<T> {

View File

@ -228,7 +228,6 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
mDoricJSE.injectGlobalJSFunction(DoricConstant.INJECT_BRIDGE, new JavaFunction() {
@Override
public JavaValue exec(JSDecoder[] args) {
String source = "Unknown";
try {
String contextId = args[0].string();
String module = args[1].string();

View File

@ -86,7 +86,7 @@ public class DoricBridgeExtension {
Callable<JavaValue> callable = new Callable<JavaValue>() {
@Override
public JavaValue call() throws Exception {
Class[] classes = method.getParameterTypes();
Class<?>[] classes = method.getParameterTypes();
Object ret;
if (classes.length == 0) {
ret = method.invoke(doricJavaPlugin);

View File

@ -15,8 +15,6 @@
*/
package pub.doric.extension.bridge;
import android.util.Log;
import pub.doric.DoricContext;
import pub.doric.async.AsyncResult;
import pub.doric.utils.DoricConstant;

View File

@ -32,7 +32,7 @@ public class DoricTimerExtension implements Handler.Callback {
private static final int MSG_TIMER = 0;
private final Handler mTimerHandler;
private final TimerCallback mTimerCallback;
private Set<Long> mDeletedTimerIds = new HashSet<>();
private final Set<Long> mDeletedTimerIds = new HashSet<>();
public DoricTimerExtension(Looper looper, TimerCallback timerCallback) {
mTimerHandler = new Handler(looper, this);
@ -73,7 +73,7 @@ public class DoricTimerExtension implements Handler.Callback {
mTimerHandler.removeCallbacksAndMessages(null);
}
private class TimerInfo {
private static class TimerInfo {
long timerId;
long time;
boolean repeat;

View File

@ -57,7 +57,7 @@ public class DoricAssetJSLoader implements IDoricJSLoader {
e.printStackTrace();
}
}
return result;
}
return result;
}
}

View File

@ -32,7 +32,7 @@ import pub.doric.async.AsyncResult;
* @CreateDate: 2019-11-23
*/
public class DoricHttpJSLoader implements IDoricJSLoader {
private OkHttpClient okHttpClient = new OkHttpClient();
private final OkHttpClient okHttpClient = new OkHttpClient();
@Override
public boolean filter(String source) {
@ -51,6 +51,7 @@ public class DoricHttpJSLoader implements IDoricJSLoader {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
try {
assert response.body() != null;
ret.setResult(response.body().string());
} catch (Exception e) {
ret.setError(e);

View File

@ -31,7 +31,6 @@ import pub.doric.Doric;
* @CreateDate: 3/29/21
*/
public class DoricPerformanceProfile {
private static final String TAG = DoricPerformanceProfile.class.getSimpleName();
public static final String PART_INIT = "Init";
public static final String STEP_CREATE = "Create";
public static final String STEP_Call = "Call";

View File

@ -40,7 +40,7 @@ public class AnimatePlugin extends DoricJavaPlugin {
public void animateRender(final JSObject jsObject, final DoricPromise promise) {
getDoricContext().getDriver().asyncCall(new Callable<Object>() {
@Override
public Object call() throws Exception {
public Object call() {
final long duration = jsObject.getProperty("duration").asNumber().toLong();
AnimatorSet animatorSet = new AnimatorSet();
getDoricContext().setAnimatorSet(animatorSet);
@ -50,7 +50,7 @@ public class AnimatePlugin extends DoricJavaPlugin {
rootNode.setId(viewId);
rootNode.blend(jsObject.getProperty("props").asObject());
} else {
ViewNode viewNode = getDoricContext().targetViewNode(viewId);
ViewNode<?> viewNode = getDoricContext().targetViewNode(viewId);
if (viewNode != null) {
viewNode.blend(jsObject.getProperty("props").asObject());
}

View File

@ -65,14 +65,14 @@ public class CoordinatorPlugin extends DoricJavaPlugin {
@Override
public Object call() throws Exception {
JSValue[] scrollableIds = argument.getProperty("scrollable").asArray().toArray();
ViewNode scrollNode = null;
ViewNode<?> scrollNode = null;
for (JSValue value : scrollableIds) {
if (scrollNode == null) {
scrollNode = getDoricContext().targetViewNode(value.asString().value());
} else {
if (value.isString() && scrollNode instanceof SuperNode) {
String viewId = value.asString().value();
scrollNode = ((SuperNode) scrollNode).getSubNodeById(viewId);
scrollNode = ((SuperNode<?>) scrollNode).getSubNodeById(viewId);
}
}
}
@ -85,7 +85,7 @@ public class CoordinatorPlugin extends DoricJavaPlugin {
JSValue target = argument.getProperty("target");
boolean isNavBar = false;
ViewNode targetNode = null;
ViewNode<?> targetNode = null;
if (target.isString() && "NavBar".equals(target.asString().value())) {
isNavBar = true;
} else if (target.isArray()) {
@ -96,7 +96,7 @@ public class CoordinatorPlugin extends DoricJavaPlugin {
} else {
if (value.isString() && targetNode instanceof SuperNode) {
String viewId = value.asString().value();
targetNode = ((SuperNode) targetNode).getSubNodeById(viewId);
targetNode = ((SuperNode<?>) targetNode).getSubNodeById(viewId);
}
}
}
@ -109,8 +109,8 @@ public class CoordinatorPlugin extends DoricJavaPlugin {
final float changingEnd = changing.getProperty("end").asNumber().toFloat();
final ViewNode finalScrollNode = scrollNode;
final ViewNode finalTargetNode = targetNode;
final ViewNode<?> finalScrollNode = scrollNode;
final ViewNode<?> finalTargetNode = targetNode;
final boolean finalIsNavBar = isNavBar;
if (finalScrollNode instanceof IDoricScrollable) {
@ -163,7 +163,7 @@ public class CoordinatorPlugin extends DoricJavaPlugin {
});
}
private void setValue(ViewNode viewNode, boolean isNavBar, String name, float value) {
private void setValue(ViewNode<?> viewNode, boolean isNavBar, String name, float value) {
if ("backgroundColor".equals(name) && isNavBar) {
getDoricContext().getDoricNavBar().setBackgroundColor((int) value);
} else {

View File

@ -32,7 +32,6 @@ import pub.doric.extension.bridge.DoricPromise;
import pub.doric.utils.DoricUtils;
import pub.doric.utils.ThreadMode;
import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
import com.github.pengfeizhou.jscore.JavaValue;

View File

@ -25,7 +25,6 @@ import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
import com.github.pengfeizhou.jscore.JavaValue;
import pub.doric.Doric;
import pub.doric.DoricActivity;
import pub.doric.DoricContext;
import pub.doric.extension.bridge.DoricMethod;

View File

@ -21,7 +21,7 @@ public class NotchPlugin extends DoricJavaPlugin {
}
@DoricMethod(thread = ThreadMode.UI)
public void inset(JSObject jsObject, final DoricPromise promise) {
public void inset(final DoricPromise promise) {
View view = getDoricContext().getRootNode().getNodeView();
int top = QMUINotchHelper.getSafeInsetTop(view);
int left = QMUINotchHelper.getSafeInsetLeft(view);

View File

@ -41,7 +41,7 @@ public class PopoverPlugin extends DoricJavaPlugin {
final JSObject jsObject = decoder.decode().asObject();
getDoricContext().getDriver().asyncCall(new Callable<Object>() {
@Override
public Object call() throws Exception {
public Object call() {
ViewGroup decorView = (ViewGroup) getDoricContext().getRootNode().getNodeView().getRootView();
if (mFullScreenView == null) {
mFullScreenView = new FrameLayout(getDoricContext().getContext());
@ -77,7 +77,7 @@ public class PopoverPlugin extends DoricJavaPlugin {
mFullScreenView.bringToFront();
String viewId = jsObject.getProperty("id").asString().value();
String type = jsObject.getProperty("type").asString().value();
ViewNode node = ViewNode.create(getDoricContext(), type);
ViewNode<?> node = ViewNode.create(getDoricContext(), type);
node.setId(viewId);
node.init(new FrameLayout.LayoutParams(0, 0));
node.blend(jsObject.getProperty("props").asObject());
@ -113,10 +113,10 @@ public class PopoverPlugin extends DoricJavaPlugin {
try {
getDoricContext().getDriver().asyncCall(new Callable<Object>() {
@Override
public Object call() throws Exception {
public Object call() {
if (value.isObject()) {
String viewId = value.asObject().getProperty("id").asString().value();
ViewNode node = getDoricContext().targetViewNode(viewId);
ViewNode<?> node = getDoricContext().targetViewNode(viewId);
dismissViewNode(node);
} else {
dismissPopover();
@ -148,7 +148,7 @@ public class PopoverPlugin extends DoricJavaPlugin {
}
}
private void dismissViewNode(ViewNode node) {
private void dismissViewNode(ViewNode<?> node) {
getDoricContext().removeHeadNode(TYPE, node);
mFullScreenView.removeView(node.getNodeView());
if (getDoricContext().allHeadNodes(TYPE).isEmpty()) {
@ -159,7 +159,7 @@ public class PopoverPlugin extends DoricJavaPlugin {
}
private void dismissPopover() {
for (ViewNode node : getDoricContext().allHeadNodes(TYPE)) {
for (ViewNode<?> node : getDoricContext().allHeadNodes(TYPE)) {
dismissViewNode(node);
}
}

View File

@ -59,7 +59,7 @@ public class ShaderPlugin extends DoricJavaPlugin {
profile.prepare(DoricPerformanceProfile.STEP_RENDER);
getDoricContext().getDriver().asyncCall(new Callable<Object>() {
@Override
public Object call() throws Exception {
public Object call() {
profile.start(DoricPerformanceProfile.STEP_RENDER);
if (getDoricContext().getContext() instanceof Activity) {
@ -71,12 +71,12 @@ public class ShaderPlugin extends DoricJavaPlugin {
String viewId = jsObject.getProperty("id").asString().value();
RootNode rootNode = getDoricContext().getRootNode();
ViewNode targetNode = rootNode;
ViewNode<?> targetNode = rootNode;
if (TextUtils.isEmpty(rootNode.getId()) && "Root".equals(jsObject.getProperty("type").asString().value())) {
rootNode.setId(viewId);
rootNode.blend(jsObject.getProperty("props").asObject());
} else {
ViewNode viewNode = getDoricContext().targetViewNode(viewId);
ViewNode<?> viewNode = getDoricContext().targetViewNode(viewId);
if (viewNode != null) {
targetNode = viewNode;
viewNode.blend(jsObject.getProperty("props").asObject());
@ -124,26 +124,26 @@ public class ShaderPlugin extends DoricJavaPlugin {
public void command(final JSObject jsObject, final DoricPromise doricPromise) {
getDoricContext().getDriver().asyncCall(new Callable<Object>() {
@Override
public Object call() throws Exception {
public Object call() {
final JSValue[] viewIds = jsObject.getProperty("viewIds").asArray().toArray();
final String name = jsObject.getProperty("name").asString().value();
final JSValue args = jsObject.getProperty("args");
ViewNode viewNode = null;
ViewNode<?> viewNode = null;
for (JSValue value : viewIds) {
if (viewNode == null) {
viewNode = getDoricContext().targetViewNode(value.asString().value());
} else {
if (value.isString() && viewNode instanceof SuperNode) {
String viewId = value.asString().value();
viewNode = ((SuperNode) viewNode).getSubNodeById(viewId);
viewNode = ((SuperNode<?>) viewNode).getSubNodeById(viewId);
}
}
}
if (viewNode == null) {
doricPromise.reject(new JavaValue("Cannot find opposite view"));
} else {
final ViewNode targetViewNode = viewNode;
DoricMetaInfo<ViewNode> pluginInfo = getDoricContext().getDriver().getRegistry()
final ViewNode<?> targetViewNode = viewNode;
DoricMetaInfo<ViewNode<?>> pluginInfo = getDoricContext().getDriver().getRegistry()
.acquireViewNodeInfo(viewNode.getType());
final Method method = pluginInfo.getMethod(name);
if (method == null) {
@ -156,7 +156,7 @@ public class ShaderPlugin extends DoricJavaPlugin {
Callable<JavaValue> callable = new Callable<JavaValue>() {
@Override
public JavaValue call() throws Exception {
Class[] classes = method.getParameterTypes();
Class<?>[] classes = method.getParameterTypes();
Object ret;
if (classes.length == 0) {
ret = method.invoke(targetViewNode);
@ -202,7 +202,7 @@ public class ShaderPlugin extends DoricJavaPlugin {
}
private Object createParam(Class clz, DoricPromise doricPromise, JSValue jsValue) {
private Object createParam(Class<?> clz, DoricPromise doricPromise, JSValue jsValue) {
if (clz == DoricPromise.class) {
return doricPromise;
} else {

View File

@ -17,7 +17,6 @@ package pub.doric.plugin;
import android.content.Context;
import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
import com.github.pengfeizhou.jscore.JavaValue;

View File

@ -20,10 +20,10 @@ import pub.doric.shader.ViewNode;
public class RefreshableNode extends SuperNode<DoricSwipeLayout> implements PullingListener {
private String mContentViewId;
private ViewNode mContentNode;
private ViewNode<?> mContentNode;
private String mHeaderViewId;
private ViewNode mHeaderNode;
private ViewNode<?> mHeaderNode;
public RefreshableNode(DoricContext doricContext) {
super(doricContext);
@ -139,7 +139,7 @@ public class RefreshableNode extends SuperNode<DoricSwipeLayout> implements Pull
}
@Override
public ViewNode getSubNodeById(String id) {
public ViewNode<?> getSubNodeById(String id) {
if (id.equals(mContentViewId)) {
return mContentNode;
}
@ -152,7 +152,7 @@ public class RefreshableNode extends SuperNode<DoricSwipeLayout> implements Pull
@Override
protected void blendSubNode(JSObject subProperties) {
String viewId = subProperties.getProperty("id").asString().value();
ViewNode node = getSubNodeById(viewId);
ViewNode<?> node = getSubNodeById(viewId);
if (node != null) {
node.blend(subProperties.getProperty("props").asObject());
}

View File

@ -37,10 +37,10 @@ import androidx.annotation.RequiresApi;
* @CreateDate: 2019-07-31
*/
public class DoricLayer extends FrameLayout {
private Path mCornerPath = new Path();
private final Path mCornerPath = new Path();
private Paint mShadowPaint;
private Paint mBorderPaint;
private RectF mRect = new RectF();
private final RectF mRect = new RectF();
private float[] mCornerRadii;
public DoricLayer(@NonNull Context context) {

View File

@ -32,7 +32,7 @@ import pub.doric.DoricContext;
* @CreateDate: 2019-07-20
*/
public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
protected ArrayList<ViewNode> mChildNodes = new ArrayList<>();
protected ArrayList<ViewNode<?>> mChildNodes = new ArrayList<>();
protected ArrayList<String> mChildViewIds = new ArrayList<>();
public GroupNode(DoricContext doricContext) {
@ -75,7 +75,7 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
}
String type = model.getProperty("type").asString().value();
if (idx < mChildNodes.size()) {
ViewNode oldNode = mChildNodes.get(idx);
ViewNode<?> oldNode = mChildNodes.get(idx);
if (id.equals(oldNode.getId())) {
//The same,skip
} else {
@ -88,7 +88,7 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
//Replace this view
mChildNodes.remove(idx);
mView.removeView(oldNode.getNodeView());
ViewNode newNode = ViewNode.create(getDoricContext(), type);
ViewNode<?> newNode = ViewNode.create(getDoricContext(), type);
newNode.setId(id);
newNode.init(this);
newNode.blend(model.getProperty("props").asObject());
@ -99,7 +99,7 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
//Find in remain nodes
int position = -1;
for (int start = idx + 1; start < mChildNodes.size(); start++) {
ViewNode node = mChildNodes.get(start);
ViewNode<?> node = mChildNodes.get(start);
if (id.equals(node.getId())) {
//Found
position = start;
@ -108,8 +108,8 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
}
if (position >= 0) {
//Found swap idx,position
ViewNode reused = mChildNodes.remove(position);
ViewNode abandoned = mChildNodes.remove(idx);
ViewNode<?> reused = mChildNodes.remove(position);
ViewNode<?> abandoned = mChildNodes.remove(idx);
mChildNodes.set(idx, reused);
mChildNodes.set(position, abandoned);
//View swap index
@ -119,7 +119,7 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
mView.addView(abandoned.getNodeView(), position);
} else {
//Not found,insert
ViewNode newNode = ViewNode.create(getDoricContext(), type);
ViewNode<?> newNode = ViewNode.create(getDoricContext(), type);
newNode.setId(id);
newNode.init(this);
newNode.blend(model.getProperty("props").asObject());
@ -131,7 +131,7 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
}
} else {
//Insert
ViewNode newNode = ViewNode.create(getDoricContext(), type);
ViewNode<?> newNode = ViewNode.create(getDoricContext(), type);
newNode.setId(id);
newNode.init(this);
newNode.blend(model.getProperty("props").asObject());
@ -141,7 +141,7 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
}
int size = mChildNodes.size();
for (int idx = mChildViewIds.size(); idx < size; idx++) {
ViewNode viewNode = mChildNodes.remove(mChildViewIds.size());
ViewNode<?> viewNode = mChildNodes.remove(mChildViewIds.size());
mView.removeView(viewNode.getNodeView());
}
}
@ -149,7 +149,7 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
@Override
protected void blendSubNode(JSObject subProp) {
String subNodeId = subProp.getProperty("id").asString().value();
for (ViewNode node : mChildNodes) {
for (ViewNode<?> node : mChildNodes) {
if (subNodeId.equals(node.getId())) {
node.blend(subProp.getProperty("props").asObject());
break;
@ -158,8 +158,8 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
}
@Override
public ViewNode getSubNodeById(String id) {
for (ViewNode node : mChildNodes) {
public ViewNode<?> getSubNodeById(String id) {
for (ViewNode<?> node : mChildNodes) {
if (id.equals(node.getId())) {
return node;
}
@ -174,7 +174,7 @@ public abstract class GroupNode<F extends ViewGroup> extends SuperNode<F> {
mChildViewIds.clear();
}
public ArrayList<ViewNode> getChildNodes() {
public ArrayList<ViewNode<?>> getChildNodes() {
return mChildNodes;
}
}

View File

@ -20,8 +20,8 @@ import android.content.Context;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSONBuilder;
import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
@ -48,8 +48,8 @@ import pub.doric.widget.HVScrollView;
@DoricPlugin(name = "Scroller")
public class ScrollerNode extends SuperNode<HVScrollView> implements IDoricScrollable {
private String mChildViewId;
private ViewNode mChildNode;
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
private ViewNode<?> mChildNode;
private final Set<DoricScrollChangeListener> listeners = new HashSet<>();
private String onScrollFuncId;
private String onScrollEndFuncId;
private DoricJSDispatcher jsDispatcher = new DoricJSDispatcher();
@ -96,7 +96,7 @@ public class ScrollerNode extends SuperNode<HVScrollView> implements IDoricScrol
}
@Override
public ViewNode getSubNodeById(String id) {
public ViewNode<?> getSubNodeById(String id) {
return id.equals(mChildNode.getId()) ? mChildNode : null;
}
@ -118,17 +118,15 @@ public class ScrollerNode extends SuperNode<HVScrollView> implements IDoricScrol
listener.onScrollChange(v, scrollX, scrollY, oldScrollX, oldScrollY);
}
if (!TextUtils.isEmpty(onScrollFuncId)) {
if (!TextUtils.isEmpty(onScrollFuncId)) {
jsDispatcher.dispatch(new Callable<AsyncResult>() {
@Override
public AsyncResult call() throws Exception {
return callJSResponse(onScrollFuncId, new JSONBuilder()
.put("x", DoricUtils.px2dp(scrollX))
.put("y", DoricUtils.px2dp(scrollY))
.toJSONObject());
}
});
}
jsDispatcher.dispatch(new Callable<AsyncResult<JSDecoder>>() {
@Override
public AsyncResult<JSDecoder> call() throws Exception {
return callJSResponse(onScrollFuncId, new JSONBuilder()
.put("x", DoricUtils.px2dp(scrollX))
.put("y", DoricUtils.px2dp(scrollY))
.toJSONObject());
}
});
}
}

View File

@ -35,14 +35,14 @@ import pub.doric.DoricContext;
* @CreateDate: 2019-11-13
*/
public abstract class SuperNode<V extends View> extends ViewNode<V> {
private Map<String, JSObject> subNodes = new HashMap<>();
private final Map<String, JSObject> subNodes = new HashMap<>();
protected boolean mReusable = false;
public SuperNode(DoricContext doricContext) {
super(doricContext);
}
public abstract ViewNode getSubNodeById(String id);
public abstract ViewNode<?> getSubNodeById(String id);
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new ViewGroup.LayoutParams(0, 0);
@ -92,7 +92,7 @@ public abstract class SuperNode<V extends View> extends ViewNode<V> {
protected abstract void blendSubNode(JSObject subProperties);
protected void blendSubLayoutConfig(ViewNode viewNode, JSObject jsObject) {
protected void blendSubLayoutConfig(ViewNode<?> viewNode, JSObject jsObject) {
viewNode.blendLayoutConfig(jsObject);
}

View File

@ -100,8 +100,6 @@ public class TextNode extends ViewNode<TextView> {
public void run() {
final JSObject dict = prop.asObject();
LinearGradient linearGradient = null;
int[] colors = null;
float[] locations = null;

View File

@ -73,7 +73,7 @@ import pub.doric.utils.DoricUtils;
*/
public abstract class ViewNode<T extends View> extends DoricContextHolder {
protected T mView;
SuperNode mSuperNode;
SuperNode<?> mSuperNode;
String mId;
protected ViewGroup.LayoutParams mLayoutParams;
private String mType;
@ -90,7 +90,7 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
private DoricLayer doricLayer;
public void init(SuperNode superNode) {
public void init(SuperNode<?> superNode) {
if (this instanceof SuperNode) {
((SuperNode<T>) this).mReusable = superNode.mReusable;
}
@ -113,7 +113,12 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
public String getType() {
if (TextUtils.isEmpty(mType)) {
mType = this.getClass().getAnnotation(DoricPlugin.class).name();
DoricPlugin annotation = this.getClass().getAnnotation(DoricPlugin.class);
if (annotation != null) {
mType = annotation.name();
} else {
mType = "Error";
}
}
return mType;
}
@ -558,7 +563,7 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
String[] getIdList() {
LinkedList<String> ids = new LinkedList<>();
ViewNode viewNode = this;
ViewNode<?> viewNode = this;
do {
ids.push(viewNode.mId);
viewNode = viewNode.mSuperNode;
@ -607,13 +612,13 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
return asyncResult;
}
public static ViewNode create(DoricContext doricContext, String type) {
public static ViewNode<?> create(DoricContext doricContext, String type) {
DoricRegistry registry = doricContext.getDriver().getRegistry();
DoricMetaInfo<? extends ViewNode> clz = registry.acquireViewNodeInfo(type);
DoricMetaInfo<? extends ViewNode<?>> clz = registry.acquireViewNodeInfo(type);
if (clz == null) {
clz = new DoricMetaInfo<>(ErrorHintNode.class);
}
ViewNode ret = clz.createInstance(doricContext);
ViewNode<?> ret = clz.createInstance(doricContext);
ret.mType = type;
if (ret instanceof ErrorHintNode) {
((ErrorHintNode) ret).setHintText(type);
@ -1053,14 +1058,13 @@ public abstract class ViewNode<T extends View> extends DoricContextHolder {
startVal,
endVal
);
setFillMode(animator, key, startVal, endVal, fillMode);
setFillMode(animator, key, startVal, fillMode);
return animator;
}
private void setFillMode(ObjectAnimator animator,
final String key,
float startVal,
float endVal,
JSValue jsValue) {
int fillMode = 0;
if (jsValue.isNumber()) {

View File

@ -173,7 +173,7 @@ public class FlexNode extends GroupNode<YogaLayout> {
}
@Override
protected void blendSubLayoutConfig(ViewNode viewNode, JSObject jsObject) {
protected void blendSubLayoutConfig(ViewNode<?> viewNode, JSObject jsObject) {
super.blendSubLayoutConfig(viewNode, jsObject);
}
@ -190,7 +190,7 @@ public class FlexNode extends GroupNode<YogaLayout> {
@Override
public void blend(JSObject jsObject) {
super.blend(jsObject);
for (ViewNode childNode : mChildNodes) {
for (ViewNode<?> childNode : mChildNodes) {
YogaNode yogaNode = this.mView.getYogaNodeForView(childNode.getNodeView());
if (yogaNode != null) {
blendSubFlexConfig(yogaNode, childNode.getFlexConfig());
@ -199,8 +199,7 @@ public class FlexNode extends GroupNode<YogaLayout> {
}
private void blendSubFlexConfig(YogaNode yogaNode, JSObject jsObject) {
if (jsObject == null) {
} else {
if (jsObject != null) {
for (String name : jsObject.propertySet()) {
JSValue value = jsObject.getProperty(name);
blendFlexConfig(yogaNode, name, value);

View File

@ -17,13 +17,13 @@ package pub.doric.shader.flowlayout;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSONBuilder;
import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue;
@ -82,7 +82,7 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
};
private int columnSpace = 0;
private int rowSpace = 0;
private Rect padding = new Rect();
private final Rect padding = new Rect();
private final RecyclerView.ItemDecoration spacingItemDecoration = new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
@ -92,10 +92,10 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
String onLoadMoreFuncId;
boolean loadMore = false;
String loadMoreViewId;
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
private final Set<DoricScrollChangeListener> listeners = new HashSet<>();
private String onScrollFuncId;
private String onScrollEndFuncId;
private DoricJSDispatcher jsDispatcher = new DoricJSDispatcher();
private final DoricJSDispatcher jsDispatcher = new DoricJSDispatcher();
private int itemCount = 0;
private boolean scrollable = true;
@ -105,7 +105,7 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
}
@Override
public ViewNode getSubNodeById(String id) {
public ViewNode<?> getSubNodeById(String id) {
RecyclerView.LayoutManager manager = mView.getLayoutManager();
if (manager == null) {
return null;
@ -246,7 +246,7 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
@Override
protected void blendSubNode(JSObject subProperties) {
String viewId = subProperties.getProperty("id").asString().value();
ViewNode node = getSubNodeById(viewId);
ViewNode<?> node = getSubNodeById(viewId);
if (node != null) {
node.blend(subProperties.getProperty("props").asObject());
} else {
@ -274,9 +274,9 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
listener.onScrollChange(recyclerView, offsetX, offsetY, offsetX - dx, offsetY - dy);
}
if (!TextUtils.isEmpty(onScrollFuncId)) {
jsDispatcher.dispatch(new Callable<AsyncResult>() {
jsDispatcher.dispatch(new Callable<AsyncResult<JSDecoder>>() {
@Override
public AsyncResult call() throws Exception {
public AsyncResult<JSDecoder> call() {
return callJSResponse(onScrollFuncId, new JSONBuilder()
.put("x", DoricUtils.px2dp(offsetX))
.put("y", DoricUtils.px2dp(offsetY))

View File

@ -157,7 +157,7 @@ class ListAdapter extends RecyclerView.Adapter<ListAdapter.DoricViewHolder> {
if (jsValue != null && jsValue.isObject()) {
JSObject jsObject = jsValue.asObject();
String id = jsObject.getProperty("id").asString().value();
final ViewNode itemNode = this.listNode.getSubNodeById(id);
final ViewNode<?> itemNode = this.listNode.getSubNodeById(id);
JSObject props = jsObject.getProperty("props").asObject();
JSValue prop = props.getProperty("actions");
if (itemNode != null && prop.isArray()) {

View File

@ -36,7 +36,6 @@ import pub.doric.shader.StackNode;
@DoricPlugin(name = "ListItem")
public class ListItemNode extends StackNode {
public String identifier = "";
private JSArray actions = null;
public ListItemNode(DoricContext doricContext) {
super(doricContext);
@ -58,33 +57,5 @@ public class ListItemNode extends StackNode {
super.blend(jsObject);
getNodeView().getLayoutParams().width = getLayoutParams().width;
getNodeView().getLayoutParams().height = getLayoutParams().height;
if (this.actions != null && this.actions.size() > 0) {
getView().setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (actions == null || actions.size() == 0) {
return false;
}
String[] items = new String[actions.size()];
final String[] callbacks = new String[actions.size()];
for (int i = 0; i < actions.size(); i++) {
JSObject action = actions.get(i).asObject();
String title = action.getProperty("title").asString().value();
String callback = action.getProperty("callback").asString().value();
items[i] = title;
callbacks[i] = callback;
}
new AlertDialog.Builder(getContext())
.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
callJSResponse(callbacks[which]);
dialog.dismiss();
}
}).show();
return true;
}
});
}
}
}

View File

@ -25,6 +25,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSNumber;
import com.github.pengfeizhou.jscore.JSONBuilder;
import com.github.pengfeizhou.jscore.JSObject;
@ -75,7 +76,7 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
@Override
protected void blendSubNode(JSObject subProperties) {
String viewId = subProperties.getProperty("id").asString().value();
ViewNode node = getSubNodeById(viewId);
ViewNode<?> node = getSubNodeById(viewId);
if (node != null) {
node.blend(subProperties.getProperty("props").asObject());
} else {
@ -110,9 +111,9 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
listener.onScrollChange(recyclerView, offsetX, offsetY, offsetX - dx, offsetY - dy);
}
if (!TextUtils.isEmpty(onScrollFuncId)) {
jsDispatcher.dispatch(new Callable<AsyncResult>() {
jsDispatcher.dispatch(new Callable<AsyncResult<JSDecoder>>() {
@Override
public AsyncResult call() throws Exception {
public AsyncResult<JSDecoder> call() {
return callJSResponse(onScrollFuncId, new JSONBuilder()
.put("x", DoricUtils.px2dp(offsetX))
.put("y", DoricUtils.px2dp(offsetY))
@ -154,11 +155,8 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
if (gestureDetector.onTouchEvent(e)) {
return true;
}
return false;
public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
return gestureDetector.onTouchEvent(e);
}
});
return recyclerView;
@ -249,12 +247,12 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
}
@Override
protected void blendSubLayoutConfig(ViewNode viewNode, JSObject jsObject) {
protected void blendSubLayoutConfig(ViewNode<?> viewNode, JSObject jsObject) {
super.blendSubLayoutConfig(viewNode, jsObject);
}
@Override
public ViewNode getSubNodeById(String id) {
public ViewNode<?> getSubNodeById(String id) {
RecyclerView.LayoutManager manager = mView.getLayoutManager();
if (manager == null) {
return null;
@ -305,14 +303,7 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
int lastItem = layoutManager.findLastVisibleItemPosition();
if (pos <= firstItem) {
defaultScrollTo(pos, smooth);
} else if (pos <= lastItem) {
// int top = getInnerView().getChildAt(pos - firstItem).getTop();
// if (smooth) {
// getInnerView().smoothScrollBy(0, top);
// } else {
// getInnerView().scrollBy(0, top);
// }
} else {
} else if (pos > lastItem) {
defaultScrollTo(pos, smooth);
}
}

View File

@ -18,6 +18,8 @@ package pub.doric.utils;
import android.os.Handler;
import android.os.Looper;
import com.github.pengfeizhou.jscore.JSDecoder;
import java.util.LinkedList;
import java.util.concurrent.Callable;
@ -28,12 +30,12 @@ import pub.doric.async.AsyncResult;
* @Author: pengfei.zhou
* @CreateDate: 2020-03-25
*/
public class DoricJSDispatcher implements AsyncResult.Callback {
private LinkedList<Callable<AsyncResult>> blocks = new LinkedList<>();
public class DoricJSDispatcher implements AsyncResult.Callback<JSDecoder> {
private final LinkedList<Callable<AsyncResult<JSDecoder>>> blocks = new LinkedList<>();
private boolean consuming = false;
private Handler mHandler = new Handler(Looper.getMainLooper());
private final Handler mHandler = new Handler(Looper.getMainLooper());
public void dispatch(Callable<AsyncResult> block) {
public void dispatch(Callable<AsyncResult<JSDecoder>> block) {
if (blocks.size() > 0) {
blocks.clear();
}
@ -44,11 +46,11 @@ public class DoricJSDispatcher implements AsyncResult.Callback {
}
private void consume() {
Callable<AsyncResult> block = blocks.pollLast();
Callable<AsyncResult<JSDecoder>> block = blocks.pollLast();
if (block != null) {
consuming = true;
try {
AsyncResult result = block.call();
AsyncResult<JSDecoder> result = block.call();
result.setCallback(this);
} catch (Exception e) {
e.printStackTrace();
@ -60,7 +62,17 @@ public class DoricJSDispatcher implements AsyncResult.Callback {
}
@Override
public void onResult(Object result) {
public void onResult(JSDecoder result) {
}
@Override
public void onError(Throwable t) {
}
@Override
public void onFinish() {
if (Looper.myLooper() == mHandler.getLooper()) {
consume();
} else {
@ -72,14 +84,4 @@ public class DoricJSDispatcher implements AsyncResult.Callback {
});
}
}
@Override
public void onError(Throwable t) {
}
@Override
public void onFinish() {
}
}

View File

@ -26,7 +26,7 @@ import pub.doric.Doric;
* @CreateDate: 2019-07-18
*/
public class DoricLog {
private static String TAG = Doric.class.getSimpleName();
private static final String TAG = Doric.class.getSimpleName();
public static void d(String message, Object... args) {

View File

@ -35,13 +35,16 @@ public class DoricMetaInfo<T extends DoricContextHolder> {
private Constructor<? extends T> pluginConstructor;
private Map<String, Method> methodMap = new ConcurrentHashMap<>();
private final Map<String, Method> methodMap = new ConcurrentHashMap<>();
private String name;
public DoricMetaInfo(Class<? extends T> pluginClass) {
try {
this.pluginConstructor = pluginClass.getDeclaredConstructor(DoricContext.class);
DoricPlugin doricPlugin = pluginClass.getAnnotation(DoricPlugin.class);
if (doricPlugin == null) {
throw new RuntimeException("Cannot find DoricPlugin annotation for " + pluginClass.toString());
}
this.name = doricPlugin.name();
Method[] methods = pluginClass.getMethods();
for (Method method : methods) {

View File

@ -114,7 +114,7 @@ public class DoricUtils {
}
}
public static Object toJavaObject(@NonNull Class clz, JSDecoder decoder) throws Exception {
public static Object toJavaObject(@NonNull Class<?> clz, JSDecoder decoder) throws Exception {
if (clz == JSDecoder.class) {
return decoder;
} else {
@ -122,7 +122,7 @@ public class DoricUtils {
}
}
public static Object toJavaObject(@NonNull Class clz, JSValue jsValue) throws Exception {
public static Object toJavaObject(@NonNull Class<?> clz, JSValue jsValue) {
if (clz == JSValue.class || JSValue.class.isAssignableFrom(clz)) {
return jsValue;
} else if (clz == String.class) {
@ -138,12 +138,13 @@ public class DoricUtils {
} else if (clz == double.class || clz == Double.class) {
return jsValue.asNumber().toDouble();
} else if (clz.isArray()) {
Class elementClass = clz.getComponentType();
Class<?> elementClass = clz.getComponentType();
Object ret;
if (jsValue.isArray()) {
JSArray jsArray = jsValue.asArray();
ret = Array.newInstance(clz, jsArray.size());
for (int i = 0; i < jsArray.size(); i++) {
assert elementClass != null;
Array.set(ret, i, toJavaObject(elementClass, jsArray.get(i)));
}
} else if (jsValue.isNull()) {