- 搭建一个或者云服务商买租用一个 discuz 论坛
- 增加一个 robot.txt 协议,写上 "Disallow: /"
- 然后改为邀请码才能注册
- 然后把主题改为黑色😊
大部分认为暗网其实就是这样,不能被搜索引擎搜录,一般人不能进入,主题还是黑色的,完美
没错,就是我
大部分认为暗网其实就是这样,不能被搜索引擎搜录,一般人不能进入,主题还是黑色的,完美
在部分华为手机上启动,启动图会变成如下模样
而我们正常的启动图是这个模样
有意思的地方在于,这个包对应的提交,我们同时打了一个包名不一样的包,用于mtl测试,但是那个包完全没问题。
在调用 getLifecycle().addObserver()
的时候报出这样的错误
java.lang.IllegalArgumentException
at androidx.lifecycle.LifecycleRegistry.upEvent(SourceFile:279)
at androidx.lifecycle.LifecycleRegistry.forwardPass(SourceFile:293)
at androidx.lifecycle.LifecycleRegistry.sync(SourceFile:333)
at androidx.lifecycle.LifecycleRegistry.addObserver(SourceFile:189)
公司因为扩展业务,新建了一个 android 项目,但是这个安卓项目明明比我们的主项目代码量少那么多,但是编译时间却比我们主项目时间长非常多。让我每次编译的时候都思考人生。
我们主项目是一个 80M 大小的App,dex 包都有 30M
,更改一行代码的时间实际上只需要 30s
不到的时间,但是新项目 apk 大小都没有10M
编译时间却要 一分多钟,有时候还需要 3分钟。
在 gradle
4.3 版本之后,gradle
提供了一个新的方法去扫描编译过程,就是
buildScan
功能,简单一点讲就是这个东西会把task
运行过程很多东西记录下来,图形化展示这些数据,让你更好的发现问题所在。
一堆折腾之后还是回来 wordpress
了,虽然 wordpress 有很多的不好,但是也有很多的好处,支持范围广,可以直接搭建,也直接支持图片上传。
对于一个只是想写作的人来说,这些功能真的是必备够用了。
先写个占位符吧,后面更新迁移方法
Bitmap.Config | |
---|---|
ALPHA_8 |
每个像素存储为单透明(alpha)通道。其实就是保存透明度而已 |
ARGB_4444 |
已经废弃的格式,推荐使用ARGB_8888 |
ARGB_8888 |
每个像素存储在4个Byte上,其实就是ARGB分别占用8bit的意思 |
HARDWARE |
特殊配置,当位图只存储在图形内存中。 |
RGBA_F16 |
每个像素存储在8个Byte上,这个我不太看得懂,就是RGBA 格式保存,每一个占用16bit,F并不知道是什么意思 |
RGBA_F16 |
每个像素存储在8个Byte上,这个我不太看得懂,就是RGBA 格式保存,每一个占用16bit,F并不知道是什么意思 |
RGB_565 |
每个像素存储在2个Byte上,只有RGB通道被编码:红色以5位精度(32个可能值)存储,绿色以6位精度存储(64个可能值),蓝色存储5位精确。 |
例:
选择的是ARGB_8888
分辨率为 100*100 的位图。
占用的内存应该是
100 * 100 * 4 = 40000 Byte = 39kB
只要记住符号上表示的是bit就很容易计算Bitmap在内存中占用的大小了
谷歌发布了一个RecyclerView 来代替ListView,然而RecyclerView 并没有ListView header 和 footer.为什么会没有呢,谷歌坑我们??显然不是。
其实ListView 也是“没有”这个功能,我们看看ListView中setAdapter 的代码片段
public void setAdapter(ListAdapter adapter) {
....
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}
...
}
我们可以看setAdapter 对是否有headerView 进行了判断,如果有headviewer的话就会对adapter 进行二次封装,所以这就是为什么我说ListView 其实是没有header和footer,这也是为什么设置了adapter之后添加header会出错的问题了,因为adapter是不一样的
既然知道了ListView 是怎么构造头尾部的,我们也可以用同样的办法给Recyclerview 构造一个
因为我使用footer 的原因是要构造一个更多加载,所以我将已构造一个更多加载为示例
**
* Created With Android Studio
* User 47
* Date 15/5/12
* Time 上午10:07
* 一个Load Adapter
*/
private class MoreAdapter extends Adapter<ViewHolder> {
public static final int LAST_ITEM_TYPE = -2333333;
private Adapter mAdapter;
private AdapterDataObserver observer = new AdapterDataObserver() {
MoreAdapter moreAdapter = MoreAdapter.this;
@Override
public void onChanged() {
notifyDataSetChanged();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
moreAdapter.notifyItemRangeChanged(positionStart,itemCount);
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
moreAdapter.notifyItemRangeInserted(positionStart,itemCount);
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
moreAdapter.notifyItemRangeRemoved(positionStart,itemCount);
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
moreAdapter.notifyItemMoved(fromPosition,itemCount);
}
};
public void setWrapAdapter(Adapter adapter){
if(adapter == null) return;
if(mAdapter != null) mAdapter.unregisterAdapterDataObserver(observer);
mAdapter = adapter;
mAdapter.registerAdapterDataObserver(observer);
}
public Adapter getWrapAdapter(){
return mAdapter;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == LAST_ITEM_TYPE)
return mMoreViewHolder;
return onRealCreateViewHolder(parent, viewType);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(position == getRealItemCount()) {
return;
}
onRealBindViewHolder(holder, position);
}
@Override
public int getItemViewType(int position) {
if(position == getRealItemCount()) return LAST_ITEM_TYPE;
return mAdapter.getItemViewType(position);
}
其实整个代码很简单,就是自己封装一个Adapter,然后可以把Adapter放到里面去,让它注册自己的数据观察者,以便到时候可以通知刷新
很多时候我们会把一个布局实例化之后添加到布局上
例如
View.inflater(context,R.layout.xxx,null);
但是即使是设置了外围布局的LayoutParam ,实例化之后的对象,也是没有LayoutParam的,所以很多时候都是加入布局后,布局给的默认LayoutParam,所以很多时候我们应该在实例化布局后,添加LayoutParam,不然你是不知道加入布局之后会发生什么事情
LayoutInflater.from(context).inflate(R.layout.xx,viewGroup,false);
上面的代码就能把最外层的布局给带入代买里面去了
静态变量,在Java中是当类被卸载的时候会被清空,一般情况下被卸载的时候是JVM结束的时候。但是在Android这里,使用的是Dalvik虚拟机,每个应用启动的时候都会实例化一个虚拟机对象,应用结束的时候就会消失,然后静态变量就会被回收了。
应用后台的时候,被回收了,当用户恢复应用的时候,静态变量就会被重置为空,就会出现问题.
项目已经上线,有用户反馈说我们的程序有bug。同时,产品狗扔下了两个发布时间不一样的需求修复,拍照功能和美颜功能,拍照功能要下一版本发布,美颜功能要下下版本发布
如何修复Bug同时,不影响新功能的开发,并且把两次的需求隔离开来.
项目初始化的时候我们新建三个分支,分别是release ,develop和master。同时,项目发布的时候我们要建立tag,通过tag我们找回对应版本的代码。
保存可以发布的或者已经发布的代码分支
保存着开发好测试过的代码,每次develop上开发好的功能都可以合并到master分支
我们的开发分支,开发过程中分享的代码
有这三个分支的前提下我们就可以从容的应对需求了。
从v1.0.0(假设出现问题的就是v1.0.0版本) tag 中 checkout出新的分支,hotfix_xxx, 修复好之后直接合并回去发布
直接在develop上开发,开发完成后合并到master上,测试过后就可以合并到release上了
从master中新建一个分支,叫feature_pretty ,在这个分支上同步开发,功能要上线的时候再合并到release分支上
这样就比较好的方式解决了上面这个问题了