对于类而言,为了让客户端获取他本身的一个实例,
最传统的方法就是提供一个公有的构造器。
一个类中
重载多个构造器
客户面对多个构造器这种API永远也记不住该用哪个构造器,
并且每次调用构造器必然会创建新的对象,
如果程序需要重复使用对象,构造器无法避免创建不必要的对象。
原文链接:https://blog.csdn.net/weixin_44870613/article/details/103651362
```java
<html>
<head>
<meta content="charset=utf-8 "/>
<script type="text/javascript">
function jsFunction2(hello){
document.getElementsByClassName("name").innerHTML = hello;
alert(hello);
}
</script>
</head>
<body>
<p>我是一个段落</p>
<p class="name">我是从android过来的</p>
<button onclick="window.ccc.aaa()">无参调用android</button>
<button onclick="window.ccc.bbb('电脑')">有参调用android</button>
</body>
</html>
简单来说,Room就是SQLite的一个封装,它充分利用注解,在编译期间自动生成查询的代码。我们要做的仅仅是在JavaBean上加入合适的注解,一个数据表就自动生成了。
Room可以和RxJava,Guava配合使用,这里不做介绍(因为我也不会用)
本篇使用Android Studio 3.5.3,使用Kotlin插件
原文链接:https://blog.csdn.net/baidu_24285051/article/details/103641020
public interface ItemClick{
void onClick(String name);
}
private ItemClick itemClick;
public void setItemClick(ItemClick itemClick){
this.itemClick = itemClick;
}
要使用Room,需要在build.gradle里添加依赖库
在dependencies中声明:
public FlowLayout(Context context) {
super(context);
}
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
int left = 0;
int top = 0;
int right = 0;
int bottom = 0;
int count = getChildCount();
if (count>0){
for (int j = 0; j < count; j++) {
View view = getChildAt(j);
view.measure(0,0);
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
right = left + width;
int widthPixels = getResources().getDisplayMetrics().widthPixels;
if (right>widthPixels){
left = 0;
right = left + width;
top = bottom + 30;
}
bottom = top + height;
view.layout(left,top,right,bottom);
left += width + 30;
}
}
}
public void add(List<String> tags){
if (tags != null&&tags.size()>0){
for (String tag : tags){
final TextView textView = new TextView(getContext());
textView.setText(tag);
addView(textView);
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
flowCallback.flowClick(textView.getText().toString());
}
});
}
}
}
public void addTextView(String name){
final TextView textView = new TextView(getContext());
textView.setText(name);
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(), textView.getText().toString(), Toast.LENGTH_SHORT).show();
flowCallback.flowClick(textView.getText().toString());
}
});
addView(textView);
}
public interface FlowCallback{
void flowClick(String name);
}
private FlowCallback flowCallback;
public void setFlowCallback(FlowCallback flowCallback){
this.flowCallback = flowCallback;
}
Room 包含 3 个主要组件:
数据库:包含数据库持有者,并作为应用已保留的持久关系型数据的底层连接的主要接入点。
Entity:表示数据库中的表。
DAO:(Data Access Object)包含用于访问数据库的方法。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edit_text"
android:hint="请输入搜索关键字" />
<Button
android:id="@+id/btn_search"
android:text="搜索"
android:textSize="30dp"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
<widgts.FlowLayout
android:layout_width="match_parent"
android:layout_height="150dp"
android:id="@+id/flow_layout"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
MVP框架相对于MVC框架来说相对复杂一些,代码量相对也要更大一些。但是MVP框架使得model层和view层之间分割开来,使用presenter作为两者之间交互的桥梁。耦合度更低更方便后期维护。
最主要的原因是:使用MVP框架即使是项目开发一般让另一个人进行开发也可以很好的入手,而不会出现MVC那种Activity分工不明确,一个类中调用几百个方法作者自己都难以搞清的情况。
下面这个是契约类,model层负责持有数据,presenter层持有数据,view层对数据进行展示。
原文链接:https://blog.csdn.net/Chickenupqingyun/article/details/103644803
private FlowLayout flowLayout;
private EditText et;
private Button btn;
private RecyclerView rv;
@Override
protected Presenter initPresenter() {
return new Presenter();
}
@Override
protected void initView(View view) {
flowLayout = view.findViewById(R.id.flow_layout);
et = view.findViewById(R.id.edit_text);
btn = view.findViewById(R.id.btn_search);
rv = view.findViewById(R.id.recycler_view);
rv.setLayoutManager(new GridLayoutManager(getActivity(),2));
flowLayout.setFlowCallback(new FlowLayout.FlowCallback() {
@Override
public void flowClick(String name) {
String url = "http://172.17.8.100/small/commodity/v1/findCommodityByKeyword?keyword="+ URLEncoder.encode(name)+"&count=10&page=1";
mPresenter.getProduct(url);
}
});
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (TextUtils.isEmpty(et.getText().toString())){
Toast.makeText(getActivity(), "不能为空", Toast.LENGTH_SHORT).show();
return;
}
flowLayout.addTextView(et.getText().toString());
String url = "http://172.17.8.100/small/commodity/v1/findCommodityByKeyword?keyword="+URLEncoder.encode(et.getText().toString())+"&count=10&page=1";
mPresenter.getProduct(url);
}
});
}
@Override
protected int layoutId() {
return R.layout.page_layout;
}
@Override
protected void initData() {
String url = "http://blog.zhaoliang5156.cn/baweiapi/"+ URLEncoder.encode("手机");
mPresenter.getHome(url);
}
@Override
public void success(Object data) {
if (data instanceof HomeEntity){
HomeEntity homeEntity = (HomeEntity) data;
flowLayout.add(homeEntity.getTags());
}else if (data instanceof ProductEntity){
ProductEntity productEntity = (ProductEntity) data;
MyAdapter myAdapter = new MyAdapter(getActivity(),productEntity.getResult());
rv.setAdapter(myAdapter);
myAdapter.setItemClick(new MyAdapter.ItemClick() {
@Override
public void onClick(String name) {
Toast.makeText(getActivity(), name, Toast.LENGTH_SHORT).show();
startActivity(new Intent(getActivity(), SecondActivity.class));
}
});
}
}
下边开始基类的抽取,首先抽取Presenter层的基类。我们在 Presenter 层直接绑定了 View 才可以拿到 View 层的引用,它们之间是强引用的关系,如果不进行解绑的话,那就会造成内存泄漏的情况发生。为了防止内存泄漏,我们在最后要解绑view。
@JavascriptInterface
public void aaa(){
Log.e("aaa", "js无参传递过来的方法");
Toast.makeText(MyApp.getContext(), "js无参传递过来的方法", Toast.LENGTH_SHORT).show();
}
@JavascriptInterface
public void bbb(String name){
Log.e("aaa", name);
Toast.makeText(MyApp.getContext(), name, Toast.LENGTH_SHORT).show();
}
接下来对Activity进行基类抽取,封装泛型同时解决内存泄漏问题。
<WebView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/webView"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:text="去调用js空参方法"/>
同上,抽取ragment对泛型进行封装,同时解决内存泄漏问题
private WebView webView;
private Button btn;
@Override
protected void initData() {
}
@Override
protected void initView() {
webView = findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("file:///android_asset/hello.html");
User user = new User();
webView.addJavascriptInterface(user,"ccc");
btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String s = "我来自android的世界";
webView.loadUrl("javascript:jsFunction2('"+s+"')");
}
});
}
@Override
protected BasePresenter initPresenter() {
return null;
}
@Override
protected int layoutId() {
return R.layout.activity_second;
}