参考:Android架构探索 RxBus 相信大家也都用过EventBus, Otto等开源库, 利用RxJava也能很简单的实现类似功能而无需引入其他库. 发送: RxBus.getDefault().send(new Object, EVENT_STEP_CHANGE); 接收: RxBus.getDefault().toObservable(Object.class, EVENT_STEP_CHANGE) .compose(this.bindToLifecycle()) .subscribe(new RxBusSubscriber() { @Override public void receive(Object data) { } }); 这里我们同样可以使用bindToLifeCycle()方法来将Observable绑定至Activity/Fragment的生命周期, 自动的在合适的时候取消订阅. 也能使用subscribeOn()与observeOn()方法做线程调度. 为了能很方便的接受事件, 而无需全部实现Subscriber的三个方法, 同样定义一个自己的RxBusSubscriber类 ToastMgr Android原生的Toast虽说不复杂, 但也不是很方便, 如果需要更换Toast的背景, 则需要写不少重复代码. 本着遵循DRY的原则, 理当将Toast封装一下。 DRY 是指Don't Repeat Yourself (摘自wikipedia),特指在程序设计以及计算中避免重复代码,因为这样会降低灵活性、简洁性,并且可能导致代码之间的矛盾,DRY是Andy Hunt 和 Dave Thomas's 的《 The Pragmatic Programmer 》书中的核心原则。 ToastMgr持有一个Toast的单例, 并且通过Toast.makeText(_context, "", Toast.LENGTH_SHORT).getView()来获取系统默认的吐司背景. 也可通过setBackgroundView(View view)来给Toast设置自定义的背景. 默认情况下只需通过以下方式调用: ToastMgr.show("toast"); 但是需要在程序初始化的时候调用如下方法, 建议使用ApplicationContext: ToastMgr.init(getApplicationContext()); 通过ToastMgr产生的Toast与系统自带的Toast有一个最大的区别就是, 不论前面有多少Toast, 都会被最后一个Toast覆盖, 然后2秒后消失. 原生自带的则是一个接一个的显示. 因为ToastMgr中的是Toast单例, 而原生的不是. Adapter 单布局 ListView/GridView + Adapter可以说是Android程序员最常用的组件了. 我们应该尽量简化Adapter的代码以提高开发效率. 首先来看看不做任何封装的Adapter需要哪些步骤: 继承自BaseAdpter 维护一个List数据并实现4个抽象方法 声明一个ViewHolder 在getView中判断convertView是否为空, 为空则inflate一个布局, 初始化ViewHolder, 初始化控件, 并将ViewHolder通过setTag设置到convertView中. 如果不为空则通过getTag将ViewHolder取出来 为控件设置值 下面的内容详细可以参考 打造万能的ListView GridView 适配器 虽然有了ViewHolder能减少很多代码量, 但是这不是极限, 还可以继续减少. 比如内部维护的List数据, 另外三个抽象方法等都是可以不用写的. 这里我们引用GitHub上的一个开源工具 base adapter helper. 现在来看看如何使用base adapter helper: public class HomeAdapter extends QuickAdapter { public HomeAdapter(Context context, int layoutResId) { super(context, layoutResId); } @Override protected void convert(BaseAdapterHelper helper, Attraction item) { helper.setText(R.id.tv_name, item.name) .setText(R.id.tv_des, item.profile) } } 可以调用如下方法修改Adapter的数据 homeAdapter.add(data); homeAdapter.addAll(list); homeAdapter.removeAll(); homeAdapter.remove(0); homeAdapter.set(0, data); ... base adapter helper的原理在此处就不赘述了, 参考 Android base-adapter-helper 源码分析与扩展. 使用base adapter helper可以减少大量重复的代码, 也可以通过扩展BaseAdapterHelper以适应自己的编程习惯. 以上就是对Android适配器的简化及优化. 但是base adapter helper使用虽然简单, 也还是有不足的地方. 比如不支持多布局, 只支持BaseAdapter, 不支持其他类型比如ViewPager的Adapter等. 以上就是单布局的基本原理与使用方法. 单布局是APP中最常用的, 下面介绍不是很常见的多布局的封装. 多布局 多布局是指一个适配器中使用一个以上的布局文件. 主要是依赖于覆写BaseAdapter中的getViewTypeCount与getItemViewType方法. 多布局使用了代理, 将convert方法代理给多个代理类去实现, 有兴趣的可以看这里, 这里只讲使用方法. 直接上代码: final QuickMultiAdapter adapter = new QuickMultiAdapter<>(this); adapter.addItemViewDelegate(new LeftDelegate()); adapter.addItemViewDelegate(new RightDelegate()); listView.setAdapter(adapter); adapter.replaceAll(getData()); class LeftDelegate implements ItemViewDelegate { @Override public int getItemViewLayoutId() { return R.layout.i_text; } @Override public boolean isForViewType(Integer item, int position) { return item % 2 == 0; } @Override public void convert(BaseAdapterHelper helper, Integer item, int position) { helper.setText(R.id.text, item + ""); } } class RightDelegate implements ItemViewDelegate { @Override public int getItemViewLayoutId() { return R.layout.i_text_right; } @Override public boolean isForViewType(Integer item, int position) { return item % 2 != 0; } @Override public void convert(BaseAdapterHelper helper, Integer item, int position) { helper.setText(R.id.text, item + ""); } } 效果: S60926-150201.jpg 两个布局的差别就是一个TextView的gravity是left, 同时有margin值, 另一个的gravity为right, 没有margin值. 如果是双数则显示gravity是left的TextView, 否则显示gravity是right的TextView. 代码也比较好理解, 接下来看看Delegate接口的声明以及每个方法的含义: /** * Adapter中多布局代理 * @param 数据源类型 * @param ViewHolder类型 */ public interface BaseItemViewDelegate { /** 布局资源id **/ int getItemViewLayoutId(); /** 判断该position是否要加载此类型的布局 **/ boolean isForViewType(T item, int position); /** * 当需要条目将被展示到界面上时, 通过此方法适配界面 * @param helper ViewHolder * @param item 数据 * @param position 位置 */ void convert(H helper, T item, int position); } ItemViewDelegate继承了BaseItemViewDelegate, 同时声明H为BaseAdapterHelper, 所以在不需要自定义AdapterHelper的情况下, 建议直接使用ItemViewDelegate: /** * ViewHolder类型为BaseAdapterHelper的快捷代理接口 */ public interface ItemViewDelegate extends BaseItemViewDelegate {} RecyclerView 使用方法与ListView/GridView一样, 只不过继承从QuickAdapter变成RecyclerAdapter. 多布局也一样, 区别只是从QuickMultiAdapter换成RecyclerMultiAdapter. 多布局例子点这里 SharedPreferences Android自带操作SharedPreferences的API个人觉得很麻烦, 也一直在想办法去改进. 最初的封装很简单也很直接, 通过简化实例化SharedPreferences以及Editor的代码, 提供一个saveString与getString的公共方法以供外部调用. 这样可以比较方便的存取字符串. 但是这种方式只能存字符串, 其他类型都要转换成字符串再存起来. 取出来也需要转换一遍. 并且每一个字符串都需要额外的去维护与之对应的键名, 因此还是不怎么方便. 设想一下, 如果需要将一个对象都存入SharedPreferences中, 用之前的方法, 则对象的属性越多, 需要维护的键就越多. 存与取的代码量会非常大. 这里可能会存在疑惑, 为何要在SharedPreferences里存取对象, 为何不使用数据库, 或者是文件? 首先, 数据库太重, 如果不是不得已的情况下还是不要用数据库的好. 文件与SharedPreferences比起来, 文件可以存更大的数据, 但是对象一般都是比较轻量的数据, 轻量的数据还是建议使用SharedPreferences来存取会方便一些. 试想一下, 登录之后我们需要缓存一些用户的数据, 如用户名, id, 头像之类的数据. 这些数据如果以User对象的形式存起来, 取的时候能直接返回User对象, 这样是不是会很方便? 要实现上述想法, 有两种办法: 反射 序列化 反射 SharedPreferencesClassHelper.init(context); SharedPreferencesClassHelper.getInstance().saveData(user); User user = SharedPreferencesClassHelper.getInstance().getData(User.class); 已经被废弃,原因看下面 序列化 通过自己写反射的实现方式有明显的缺陷, 首先目前只支持了4种类型int, long, boolean, String, 如果要扩展只能修改SharedPreferencesHolder的getData与setData方法. 其次, 每一个类对应一个文件比较浪费资源, 同时效率也不高. 最后SharedPreferencesClassHelper会缓存使用过的SharedPreferencesHolder对象, 内存有一定开销. 因此上述代码已经被废弃了, 接下来来实现第二种方式, 通过序列化来存储对象. 其主要思想是将对象转换成JSON字符串存入SharedPreferences中, 取对象的时候再对JSON做一次转换. 第三方序列化库有挺多, 但是由于CoreLibs里本身使用了GSON, 因此此处也选用GSON来对对象进行转换. 使用方法: PreferencesHelper.init(getApplicationContext); // 此处一定要使用ApplicationContext PreferencesHelper.saveData(user); User user = PreferencesHelper.getData(User.class); 使用起来要方便多了, 建议不要使用PreferencesHelper存过于复杂的对象, 也不要存带有Bitmap或其他复杂属性的对象, 仅仅存储一些简单的, 由基本类型构成的实体类. 下拉刷新与自动加载 下拉刷新是Android App开发中非常常用的功能, 网上也有很多开源的下拉刷新控件. CoreLibs中原先使用的handmark pulltorefresh, 现在选用的则是 Ultra-Pull-To-Refresh. 新的PTR框架有如下优点: 轻量 理论上支持所有的View 易扩展 易自定义 性能不错 具体的使用方法请参考上面的链接, 这里就不再赘述了. 但是呢, Ultra ptr也不是没有缺点, 比如库中提供了Lollipop风格的下拉头部, 如果想要在每一个下拉控件中使用还需要加入不少代码. 然后每次使用下拉组件的时候需要一些相似的配置代码. 最主要的是Ultra ptr只支持下拉, 而不支持加载更多. 因此我们需要扩展一下这个库, 目标有两个: 默认头部变为Lollipop风格, 去掉重复代码, 使用更简洁 加入自动加载更多 - auto load more. ptr的扩展类均位于com.corelibs.views.ptr下. 以下是包结构: | ptr | layout 扩展的布局 -PtrAutoLoadMoreLayout //自动加载更多布局 -PtrLollipopLayout //Lolipop头部风格布局 | loadmore | adapter -GridViewAdapter //GridView系列适配器 -ListViewAdapter //ListView系列适配器 -LoadMoreAdapter //自动加载更多的适配类 -RecyclerViewAdapter //RecyclerView系列适配器 | widget -AutoLoadMoreGridView //自动加载更多的GridView -AutoLoadMoreListView //自动加载更多的ListView -AutoLoadMoreSwipeMenuListView //自动加载更多的带侧滑菜单的ListView -AutoLoadMoreRecyclerView //自动加载更多的RecyclerView -AutoLoadMoreHandler //自动加载更多的真正处理类 -AutoLoadMoreHook //PtrAutoLoadMoreLayout的child需实现此类以供PtrAutoLoadMoreLayout获取AutoLoadMoreHandler -OnScrollListener //兼容AdapterView与RecyclerView的OnScrollListener layout.PtrLollipopLayout Activity代码: @Bind(R.id.ptrLayout) PtrLollipopLayout ptrLayout; ptrLayout.setRefreshCallback(new PtrLollipopLayout.RefreshCallback() { @Override public void onRefreshing(PtrFrameLayout frame) { ptrLayout.getPtrView().setText("我被刷了"); ptrLayout.complete(); } }); 用法非常简单, 只需使用PtrLollipopLayout包裹任意你想要刷新的控件即可. 在代码中, 如果在声明PtrLollipopLayout时加上泛型, 如PtrLollipopLayout, 就可以使用ptrLayout.getPtrView()将PtrLollipopLayout内的TextView取出. 如果不加泛型, 则需要单独为TextView设置id, 并使用ButterKnife bind出来. 两种方式均可. PtrLollipopLayout内部默认使用了Lollipop风格的下拉头部, 并且做了一些配置工作. 我们同样可以在代码中为PtrLollipopLayout做一些个性化的配置, 如通过setHeaderView(View header)设置自己的头部, 请注意, 自定义的头部必须实现PtrUIHandler接口. 如果出现PtrLollipopLayout解决不了的滑动冲突, 可以调用setPtrHandler(PtrHandler ptrHandler)自行处理滑动. 以下是几个需要注意的点: 此控件只能包含一个子View. 此控件仅支持下拉刷新, 如果需要自动加载, 请使用PtrAutoLoadMoreLayout 如果出现横向滑动冲突, 请设置disableWhenHorizontalMove(boolean)为true. 如果不想为child设置id并使用findViewById取出, 可以在声明PtrLollipopLayout的时候带上child类型的泛型, 然后就可以使用getPtrView()取出child. 如PtrLollipopLayout. 刷新完成或加载完成后请调用complete(). layout.PtrAutoLoadMoreLayout 接下来是第二个目标 - 自动加载更多. 先看例子: Activity代码: @Bind(R.id.ptrLayout) PtrAutoLoadMoreLayout ptrLayout; protected void init(Bundle savedInstanceState) { ptrLayout.setLoadingBackgroundColor(0xff333333); // 设置自动加载视图的背景颜色 adapter = new MyListAdapter(context); listView.setAdapter(adapter); // 为AutoLoadMoreListView设置Adapter adapter.addAll(getData()); // 为adapter添加数据 // 设置刷新和加载回调 ptrLayout.setRefreshLoadCallback(new PtrAutoLoadMoreLayout.RefreshLoadCallback() { @Override public void onRefreshing(PtrFrameLayout frame) { adapter.replaceAll(getData()); // 替换adapter中的数据 ptrLayout.enableLoading(); // 重新启用自动加载 ptrLayout.complete(); // 刷新完成 } @Override public void onLoading(PtrFrameLayout frame) { count++; // 模拟页数++ handler.postDelayed(new Runnable() { // 模拟网络加载延迟 @Override public void run() { adapter.addAll(getData()); // 将数据加入adapter中. ptrLayout.complete(); // 加载完成 if (count > 2) ptrLayout.disableLoading(); // 禁用自动加载 } }, 1500); } }); } 使用带自动加载的下拉刷新就要比单纯的下拉刷新复杂的多. 这种时候就不能使用PtrLollipopLayout而需要使用PtrAutoLoadMoreLayout. 一般情况下, 自动加载更多只会出现在有ListView/GridView的情况下. 因此PtrAutoLoadMoreLayout的子视图基本都是ListView/GridView, 或他们的派生类. 但是如果直接使用PtrAutoLoadMoreLayout加上ListView/GridView, 也是无法实现自动加载的。 不仅没有效果, 还会报如下错误: java.lang.IllegalStateException: PtrAutoLoadMoreLayout child should implement AutoLoadMoreHook 这是因为PtrAutoLoadMoreLayout只是一个外壳, 本身只带有下拉刷新的功能, 不带有自动加载的功能. PtrAutoLoadMoreLayout所有有关自动加载的api全部是代理至另外一个类 - AutoLoadMoreHandler. AutoLoadMoreHandler才是真正处理自动加载功能的类. PtrAutoLoadMoreLayout需要借助AutoLoadMoreHook来获取AutoLoadMoreHandler, 因此PtrAutoLoadMoreLayout的子控件必须实现AutoLoadMoreHook. 现在PtrAutoLoadMoreLayout就可以通过getLoadMoreHandler来获取AutoLoadMoreHandler实现自动加载更多的功能了. 那么, 例子中的AutoLoadMoreListView又是什么鬼? AutoLoadMoreListView是CoreLibs中预定义好的一个控件, 它实现了AutoLoadMoreHook. 如果我们需要一个带自动加载的ListView, 就可以使用AutoLoadMoreListView. AutoLoadMoreListView全部代码: public class AutoLoadMoreListView extends ListView implements AutoLoadMoreHook { public AutoLoadMoreListView(Context context) { super(context); } public AutoLoadMoreListView(Context context, AttributeSet attrs) { super(context, attrs); } public AutoLoadMoreListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public AutoLoadMoreHandler getLoadMoreHandler() { return new AutoLoadMoreHandler<>(getContext(), new ListViewAdapter(this)); } } AutoLoadMoreListView的代码非常简单, 除了三个继承自ListView需要实现的构造函数外, 就只有一个实现了AutoLoadMoreHook的getLoadMoreHandler方法. 该方法中也只是new了一个AutoLoadMoreHandler对象并返回而已. 如果我们有一个自定义的ListView, 实现了侧滑菜单, 名字叫SwipeMenuListView, 我们想要为SwipeMenuListView加上下拉和自动加载怎么办? 很简单, 定义一个新的继承自SwipeMenuListView, 并且实现了AutoLoadMoreHook的控件, 然后我们在PtrAutoLoadMoreLayout中包含该控件即可. 使用方法除了SwipeMenuListView自己的API外, 其他与默认的ListView完全一样. 以下是使用PtrAutoLoadMoreLayout需要注意的几个地方: 如果只需下拉刷新功能, 请使用PtrLollipopLayout 此控件中的child view必须实现AutoLoadMoreHook 此控件是对AutoLoadMoreHandler功能的转发. AutoLoadMoreHook的getLoadMoreHandler()需要的就是AutoLoadMoreHandler. 刷新完成或加载完成后请调用complete(), 而不是refreshComplete()或loadingFinished(). 总结 下面总结一下PtrLollipopLayout与PtrAutoLoadMoreLayout在使用上的相同点与区别: 只有下拉刷新功能时应该使用PtrLollipopLayout, 带有自动加载更多时应该使用PtrAutoLoadMoreLayout. 两者都应该使用complete()方法来结束刷新或者加载状态. PtrLollipopLayout使用setRefreshCallback(RefreshCallback callback)来设置回调. PtrAutoLoadMoreLayout使用setRefreshLoadCallback(RefreshLoadCallback callback)来设置回调. RefreshLoadCallback继承自RefreshCallback, 比RefreshCallback多了onLoading方法. RefreshCallback定义在PtrLollipopLayout内, RefreshLoadCallback定义在PtrAutoLoadMoreLayout内. PtrLollipopLayout与PtrAutoLoadMoreLayout都只能包含一个子视图. PtrLollipopLayout子视图可以是任意View, 但是PtrAutoLoadMoreLayout的子视图必须实现AutoLoadMoreHook接口. 状态栏适配 由于不同版本的系统的原因,很多时候我们需要对状态栏做不同的支持方案,主要是针对4.4,5.0以及6.0三种版本的系统。这里统一的使用的一种适配方案,避免自己写复杂的判断逻辑。主要原理如下: 由于不同版本的系统的原因,很多时候我们需要对状态栏做不同的支持方案,主要是针对4.4,5.0以及6.0三种版本的系统。这里统一的使用的一种适配方案,避免自己写复杂的判断逻辑。主要原理如下: 将Activity设置为全屏模式,使Activity能渗透到状态栏下,可以通过xml或者代码设置 将状态栏设置为透明色 自定义标题栏(可使用ToolBar,但考虑到项目里的标题栏完全不符合Android规范,因此使用的是完全自定义的标题栏),在标题栏上方多增加一块区域,刚好和状态栏大小一致 设置标题栏的额外区域的颜色,以达到另辟蹊径地改变状态栏地颜色 最后是需要解决一个manifest中的windowSoftInputMode属性在全屏模式下的bug 下面我们跟着这个思路一步步看如何去做状态栏适配: 在manifest中的application节点里,设置theme属性为corelibs的AppBaseCompactTheme 在BaseActivity的OnCreate里增加全屏以及透明状态栏的代码(默认已设置好,无需额外代码): @Override protected void onCreate(Bundle savedInstanceState) { ... setTranslucentStatusBar(); ... } 自定义一个标题栏(NavBar),继承自com.corelibs.views.navigation.TranslucentNavBar。然后覆写三个构造函数(注意,两个参数的一定要覆写)以及两个抽象函数getLayoutId和initView。这里可以直接使用ButterKnife的注解。接着就可以调用一系列设置颜色以及背景图片的方法来达到适配状态栏的效果。示例: 将NavBar放到布局文件里即可,注意根节点不能使用fitSystemWindows=“true”。 如果Activity或者Fragment中有使用EditText,并且windowSoftInputMode是adjustResize的情况下,软键盘弹出不会Resize布局。要解决这个问题需要在Activity或者Fragment添加一行代码即可: AndroidBug5497Workaround.assistActivity(activity); 扩展 TranslucentNavBar具体有哪些方法可以在源码里看到,都有注释,这里就不赘述了。 setTranslucentStatusBar会判断当前系统版本,将Activity设置为全屏,并将状态栏设置为透明 如果需要使用大图作为背景,并且希望图片渗透到状态栏下,可以调用TranslucentNavBar的setTransparentColor()来将标题栏也设置为透明,然后使用布局将标题栏覆盖到大图背景上即可。 AndroidBug5497Workaround 当初遇到软键盘弹起布局不Resize的问题的时候,也是Google了很久才在StackOverFlow找到答案(具体链接忘记了)。AndroidBug5497Workaround这个类的思路就是基于那篇文章 - 利用为Activity的content view设置 OnGlobalLayoutListener来监听布局的变化。通过判断何时弹起了软键盘来手动设置content view的高度,以此模拟adjustResize的效果。 在此基础上,我加入了一些基于现状的扩展。比如键盘弹起后手动设置的高度要计算状态栏的高度,低于4.4的版本的系统不计算状态栏,不全屏的Activity也不计算。又比如某些机型会有底栏,这个底栏的高度要考虑在内,比如谷歌原生的系统,以及典型的华为系统。其中华为系统的底栏高度计算方式又因为系统版本各有不同(很坑!)。因此在适配上花了不少时间。有兴趣的可以看看源码(不好意思,没有注释)。 圆角 圆角或圆形图片在Android是很常用的. 在CoreLibs中, 圆角相关均位于views包下的roundedimageview包中. 以下是包结构: | roundedimageview -RoundedDrawable 圆角Drawable, RoundedImageView与RoundedTransformationBuilder 内部均是使用RoundedDrawable来做圆角 或者圆形效果 -RoundedImageView 圆角ImageView, 任意图片在此控件中均可显示成圆角或圆形 -RoundedTransformationBuilder 圆角TransformationBuilder, 可配合Picasso使用产生圆角或圆形效果. RoundedDrawable 首先来看看RoundedDrawable. 实现圆角最常见的就是利用Xfermode或Shader. RoundedDrawable就是使用的BitmapShader. 具体BitmapShader的原理或者用法可以自行谷歌. RoundedDrawable提供了两个方法将Drawable/Bitmap转换成RoundedDrawable: public static Drawable fromDrawable(Drawable drawable); public static RoundedDrawable fromBitmap(Bitmap bitmap); fromDrawable方法内部最终会将Drawable中的Bitmap取出赋值给RoundedDrawable并返回. RoundedDrawable还提供了一系列方法用以描述圆角信息, 如上下左右各个角的圆角角度, 或者是否是圆形等: public RoundedDrawable setCornerRadius(Corner corner, float radius); public RoundedDrawable setCornerRadius(float topLeft, float topRight, float bottomRight, float bottomLeft); public RoundedDrawable setOval(boolean oval); ... 最后在draw方法中, 则会根据这些信息进行绘制, 调用canvas.drawRoundRect或canvas.drawOval得到圆角或圆形图片. 当然RoundedDrawable内部比这里说的复杂, 其内部会对不同的scaleType做适配, 不同的Drawable做适配, 以及其他兼容性问题. 也提供了一些设置Alpha, Shader的TileMode等方法. RoundedImageView 我们可以使用RoundedImageView来显示圆角或圆形图片. 用法很简单: XML: 代码: RoundedImageView imageView; imageView.setOval(true); imageView.setCornerRadius(50); imageView.setCornerRadius(50, 50, 50, 50); RoundedTransformationBuilder 如果觉得使用自定义控件太麻烦, 则可以使用RoundedTransformationBuilder配合Picasso实现圆角. 使用系统默认ImageView即可. 首先看看用法: 圆形: int size = (int) getResources().getDimension(R.dimen.avatar_height); Picasso.with(context).load(user.icon).resize(size, size).centerCrop() .transform(new RoundedTransformationBuilder().oval(true) .build()).into(ivIcon); 圆角: Picasso.with(context).load(user.icon).resize(size, size).centerCrop() .transform(new RoundedTransformationBuilder().cornerRadius(50) .build()).into(ivIcon); Picasso.with(context).load(user.icon).resize(size, size).centerCrop() .transform(new RoundedTransformationBuilder() .cornerRadiusTopLeft(50) .cornerRadiusBottomLeft(50) .cornerRadiusTopRight(50) .cornerRadiusBottomRight(50) .build()).into(ivIcon); RoundedTransformationBuilder内部也是使用了RoundedDrawable.fromBitmap(source)方法, 将源Bitmap转化为目标Bitmap. 具体原理是十分简单, 这里就不做过多解释. 标签导航 标签导航是常见的几种APP导航模式之一. 我们会经常用到这种模式. 使用标签导航的APP比较著名的有微信。 通常的做法是在底部写几个RadioButton, 或者是ImageView加TextView来模拟单选. 然后在Activity中使用OnClickListener来控制每个标签的状态, 同时还需要控制每个Fragment的创建与销毁, 显示与隐藏. 代码量不少, 如果每个项目都这么写会浪费很多精力与成本. 因此我们需要一个控件, 来代替OnClickListener去维护标签的状态, 以及Fragment的状态. 我们需要做的只是告诉这个控件, 每个标签长什么样, 标签对应的Fragment的类是什么, 需不需要参数等. 需求 下面我们试着实现以下UI效果: 微信截图_20160411182840.png 上述效果图在严格意义上来说不算是标签导航, 但是从开发来看, 实现的方式类似. 以下是具体需求: 有四个标签, 分别是心理测试, 心情圈, 健步走以及个人中心, 每个标签分别在当前页面内切换标签页. 点击中间的加号按钮则需要跳转到另一个页面, 当前页面则继续显示之前的标签页. 首先我们来分析一下重点: 中间加号的UI效果实现 点击加号跳转新的Activity, 并保持当前的标签页 如果没有中间的加号, 使用FragmentTabHost就能实现, 具体用法可以参考Android常用控件之FragmentTabHost的使用. 但是有了中间的加号FragmentTabHost就力不从心了, 因为FragmentTabHost的每一个标签都要对应一个Fragment, 不能对应Activity, 也无法对点击事件做拦截. 通过查看源码发现OnTabChangeListener也是在标签切换完成之后才会回调. 因此FragmentTabHost无法完成上述需求. 怎么办呢? 引入InterceptedFragmentTabHost. InterceptedFragmentTabHost InterceptedFragmentTabHost是CoreLibs中对FragmentTabHost的扩展, 实现了tab切换拦截功能. 一旦多了拦截功能, 就能实现上述需求了. 比如FragmentTabHost中实际上是有5个标签, 包含了中间的加号. 我可以通过设置拦截监听器, 检测一旦用户点击了第三个标签, 就不进行切换操作, 而是跳转至一个新的Activity. 由于通过继承FragmentTabHost没法很好的实现拦截功能, 并且FragmentTabHost内部只是引用了几个Android内部的id资源, 没有其他内部资源, 因此我们完全可以将FragmentTabHost的源码复制出来放到自己的项目中, 而不会出现编译不通过的后果. InterceptedFragmentTabHost就是通过这种方式对FragmentTabHost扩展. 接下来看看如何使用InterceptedFragmentTabHost. InterceptedFragmentTabHost中提供了如下方法来设置拦截监听器: InterceptedFragmentTabHost的用法与FragmentTabHost基本完全一致, 唯一不同的就是多了setTabChangeInterceptor方法. 由于FragmentTabHost需要我们提供每个标签对应的tab, 因此我们可以声明一个String数组: String[] tabTags = new String[] { getString(R.string.tab_test), getString(R.string.tab_mood), getString(R.string.tab_add_mood), getString(R.string.tab_pm), getString(R.string.tab_me) }; 有了tabTags, 我们就可以跟据TabChangeInterceptor中传来的tabId来判断用户点击的是哪个标签了: interceptedFragmentTabHost.setTabChangeInterceptor(new TabChangeInterceptor() { @Override public boolean canTab(String tabId) { return !tabId.equals(tabTags[2]); // 判断点击的是否是第三个标签 } @Override public void onTabIntercepted(String tabId) { toAddMood(); // 跳转Activity } }); TabChangeInterceptor的用法很简单, 每当用户点击一个非当前标签的标签时, InterceptedFragmentTabHost都会根据canTab方法的返回值来判断是否能做切换操作. 如果返回true, 意味着能切换, 返回false则意味不能切换. !tabId.equals(tabTags[2])这行代码意味着只要点击的不是第三个标签, canTab都会返回true, 如果是第三个, 则返回false. 一旦canTab返回false, InterceptedFragmentTabHost会紧接着调用onTabIntercepted方法, 我们可以在此方法中做一些其他的事情, 如跳转Activity. TabNavigator 使用FragmentTabHost虽然不需要控制点击事件以及Fragment的切换, 但是还是需要做一些Tab页设置等工作. 这些逻辑也可以抽出一个公共类 - TabNavigator. TabNavigator只需实现一个接口, 加上一行代码, 就可以配置好FragmentTabHost: private TabNavigator navigator = new TabNavigator(); navigator.setup(context, tabHost, content, getSupportFragmentManager(), R.id.real_tab_content); 实现 下面我们来看看具体如何使用TabNavigator加InterceptedFragmentTabHost来实现前面提到的UI效果图. Activity布局 首先标签导航一般是位于主页, 因此我们来看看MainActivity的布局: mesure.png 完整的MainActivity代码: public class MainActivity extends BaseActivity implements TabNavigator.TabNavigatorContent { public static final int ADD_MOOD_POSITION = 2; @Bind(android.R.id.tabhost) InterceptedFragmentTabHost tabHost; private TabNavigator navigator = new TabNavigator(); private String[] tabTags; private int[] imageResIds = new int[] { R.drawable.tab_test_icon, R.drawable.tab_mood_icon, 0, R.drawable.tab_pm_icon, R.drawable.tab_me_icon }; public static Intent getLaunchIntent(Context context) { return new Intent(context, MainActivity.class); } @Override protected int getLayoutId() { return R.layout.activity_main; } @Override protected void init(Bundle savedInstanceState) { tabTags = new String[] { getString(R.string.tab_test), getString(R.string.tab_mood), getString(R.string.tab_add_mood), getString(R.string.tab_pm), getString(R.string.tab_me) }; navigator.setup(this, tabHost, this, getSupportFragmentManager(), R.id.real_tab_content); navigator.setTabChangeInterceptor(new TabChangeInterceptor() { @Override public boolean canTab(String tabId) { return !tabId.equals(tabTags[ADD_MOOD_POSITION]); } @Override public void onTabIntercepted(String tabId) { toAddMood(); } }); } @Override protected BasePresenter createPresenter() { return null; } @Override public View getTabView(int position) { View view; if (position == ADD_MOOD_POSITION) { view = getLayoutInflater().inflate(R.layout.view_tab_add, null); return view; } else { view = getLayoutInflater().inflate(R.layout.view_tab_content, null); } ImageView iv = (ImageView) view.findViewById(R.id.iv_tab_icon); TextView tv = (TextView) view.findViewById(R.id.tv_tab_text); iv.setImageResource(imageResIds[position]); tv.setText(tabTags[position]); return view; } @Override public Bundle getArgs(int position) { return null; } @Override public Class[] getFragmentClasses() { return new Class[] { TestFragment.class, MoodFragment.class, AddMoodFragment.class, PedometerFragment.class, MeFragment.class }; } @Override public String[] getTabTags() { return tabTags; } private void toAddMood() { startActivity(AddMoodActivity.getLaunchIntent(MainActivity.this)); } } 其他功能:图片缩放、滑动选择、弹窗、自适应高度的Imageview、常用控件-CircularBar(圆形进度条)详情点这里 你可能感兴趣的:(Corelibs-master框架使用说明(二)) Openssl与网络安全 Sallyyym 知识openssl网络安全 openssl一openssl简史二openssl组成三openssl优缺点四openssl功能一openssl简史openssl是一个开放源代码的SSL协议的产品实现,采用C语言作为开发语言,具备了跨系统的性能。Openssl最早版本在1995年发布的,1998年后开始由openssl项目组维护和开发。openssl的源代码库可以从官网链接:https://www.openssl.org/.支持 MySQL 默认事务隔离级别及原因 少林码僧 mysql数据库 MySQL默认事务隔离级别及原因一、引言在MySQL数据库中,事务隔离级别决定了一个事务与其他事务之间的隔离程度。不同的隔离级别会对数据库的并发性能和数据一致性产生不同的影响。了解MySQL默认的事务隔离级别以及选择这个级别的原因,对于正确使用数据库事务和优化数据库性能至关重要。二、MySQL的事务隔离级别MySQL支持四种事务隔离级别,分别是:读未提交(Readuncommitted):一个事务 测试用例编写规范 车载测试职场人 车载测试软件测试测试用例 在车载项目开发过程中,离不开测试工作,现在越来越多的人涌入测试工作岗位,测试也是一个项目关键的一环,一个重要的角色,包括供应商释放每版软件时的全量测试,也包括主机厂的验收测试。如何做好测试工作,避免产生重复工作呢?离不开一份规范的测试用例做支撑,测试用例设计的规范一般是怎么样呢?今天一起来探讨一下。规范测试用例的背景是什么呢?主要有两个维度,首先是为保证测试用例对需求的覆盖率,第二个就是对单个功能 Unity之IK(反向动力学) winds_tide Unityunity游戏引擎 IKInverseKinematic即反向动力学,在骨骼动画中构建骨骼的方法被称为正向动力学。通常来说是父骨骼带动子骨骼旋转或移动,而反向动力学则是子骨骼带动父骨骼旋转或移动。举个例子来说,正向动力学下,我们用手控制鼠标移动,反向动力学下则是鼠标控制我们的手移动。二如何使用首先需要在状态机中开启IK设置。Unity已经定义了一个Ik回调函数——OnAnimatorIK,我们可以通过调用相关API来 测试用例的编写 旧巷歌 测试测试用例黑盒测试 测试用例的编写:工作:编写用例,执行用例(依据测试)一、熟悉工作流程(1)分析需求文档(文档有的功能都分析一遍)(2)xmind图把测试点梳理出来,测试点(3)根据测试点取编写测试用例-------------------------------------------------------------------------------二、了解测试用例(1)查看发给你们的模板必填项:1.1用例 petalinux-build ERROR Ret0 嵌入式硬件 最近编译Xilinx的固件的时候报了一个错,看的我云里雾里,一度认为ubuntu的版本跟petalinux的版本不匹配,想要重新安装操作系统和编译环境,想想都头大。petalinux-create-tproject--templatezynqMP-npetalinux-config--get-hw-description=./petalinux-build第二条命令导入的zu11eg的hdf然后就 学习threejs,使用MeshBasicMaterial基本网格材质 gis分享者 gis工程师threejsthreejsBasicMaterial基本网格材质 ⚕️主页:gis分享者⚕️感谢各位大佬点赞收藏⭐留言加关注✅!⚕️收录于专栏:threejsgis工程师文章目录一、前言1.1☘️THREE.MeshBasicMaterial二、使用MeshBasicMaterial基本网格材质1.☘️实现思路2.☘️代码样例一、前言本文详细介绍如何基于threejs在三维场景中使用MeshBasicMaterial基本网格材质,亲测可用。希望能帮助到您。 autok3s搭建k3s ha集群并支持gpu调度 StevenforAI 容器kubernetesGPUkubernetesgpu算力容器 本文描述了如何利用autok3s搭建k3s集群,同时支持对gpu的调用和切分。文章目录前言一、autok3s是什么1.k3s2.autok3s二、部署步骤1.autok3s部署2.创建集群三、QA总结前言公司新进了一台8卡a800的机器,老板要求将这台机器做成算力节点。之前利用autok3s在单机上搭建过k3d集群(autok3s单机搭建k3d集群并支持gpu调度),尝到了autok3s部署k3s 鸿蒙开发—UI框架概述 移不动开发技术 鸿蒙开发harmonyosui华为程序员学习Android开发移动开发 基本概念UI框架HarmonyOS提供了一套UI开发框架,即方舟开发框架(ArkUI框架)。方舟开发框架可为开发者提供应用UI开发所必需的能力,比如多种组件、布局计算、动画能力、UI交互、绘制等。方舟开发框架针对不同目的和技术背景的开发者提供了两种开发范式,分别是基于ArkTS的声明式开发范式(简称“声明式开发范式”)和兼容JS的类Web开发范式(简称“类Web开发范式”)。以下是两种开发范式的简 【2025年春季】全国CTF夺旗赛-从零基础入门到竞赛,看这一篇就稳了! 白帽子凯哥 web安全网络安全pythonlinuxCTF夺旗赛 基于入门网络安全/黑客打造的:黑客&网络安全入门&进阶学习资源包目录一、CTF简介二、CTF竞赛模式三、CTF各大题型简介四、CTF学习路线4.1、初期1、html+css+js(2-3天)2、apache+php(4-5天)3、mysql(2-3天)4、python(2-3天)5、burpsuite(1-2天)4.2、中期1、SQL注入(7-8天)2、文件上传(7-8天)3、其他漏洞(14-15 scratch闪亮登场 2024年9月scratch二级真题 中国电子学会 图形化编程 scratch二级真题和答案解析 小兔子编程 scratch案例scratch闪亮登场scratch二级真题scratch信息素养题目24年9月scratch二级题scratch考级二级真题scratch等级考试二级真题 目录scratch闪亮登场一、题目要求1、准备工作2、功能实现二、案例分析1、角色分析2、背景分析3、前期准备三、实现流程1、案例分析2、详细过程四、程序编写五、考点分析六、推荐资料1、入门基础2、蓝桥杯比赛3、考级资料4、视频课程5、python资料scratch闪亮登场2024年9月电子学会图形化编程Scratch等级考试二级真题一、题目要求1、准备工作1.保留默认小猫角色;2.添加背景Neo 系统架构设计师【论文】: 论面向服务架构设计及其应用(包括解题思路和经典范文) 数据知道 系统架构软考高级系统架构设计师面向服务架构论文 文章目录真题题目(2015年试题3、2018年试题3)论文解题思路素材准备精品范文赏析摘要正文总结真题题目(2015年试题3、2018年试题3)题目:论面向服务架构设计及其应用面向服务架构(Service-OrientedArchitecture,SOA)是一种应用框架,将日常的业务应用划分为单独的业务功能服务和流程,通过采用良好定义的接口和标准协议将这些服务关联起来。通过实施甚于SOA的系统架构 常用的 UI 自动化测试框架的介绍、优缺点、使用场景和适用范围 Zero_pl 自动化 以下是常用的UI自动化测试框架的介绍、优缺点、使用场景和适用范围,涵盖**Selenium**、**Appium**、**Airtest**等框架。---###**1.Selenium****简介**:Selenium是一个广泛使用的开源WebUI自动化测试框架,支持多种语言和浏览器。**优点**:-支持多种浏览器(Chrome、Firefox、Safari等)。-跨平台支持(Windows、Ma charles安装、使用charles进行手机抓包的教程 Zero_pl 测试工具 Charles安装及使用教程(包含手机抓包)一、Charles安装1.下载Charles:•访问Charles官方网站:CharlesProxyhttps://www.charlesproxy.com/。•根据你的操作系统下载相应版本的安装包。2.安装Charles:•双击下载的安装文件,按照安装向导完成安装。3.启动Charles:•安装完成后,双击Charles图标启动程序。二、Charles C与C++ —— 深度剖析区别 Exhausted、 CC++c语言c++算法开发语言 目录一、C和C++深度剖析1.编程范式2.内存管理3.标准库4.运行效率5.应用场景二、总结三、其他值得关注的差异一、C和C++深度剖析1.编程范式C:是一种结构化编程语言,以过程式编程为核心。代码以函数和模块的形式组织,程序执行流程由函数调用和控制语句来决定。这种结构化组织方式清晰易懂,适合开发相对简单的程序,比如操作系统内核和嵌入式系统。优点:代码逻辑清晰,效率高,适合底层开发。缺点:代码复用 快速幂(竞赛必备) ん贤 蓝桥杯算法c++c语言 一、概念:快速幂是一种高效的指数运算方法,通过指数折半或二进制位运算减少计算次数。它的核心思想是利用二进制表示法或指数折半来加速计算,从而避免大量的循环操作。二、学习路径:了解基本概念掌握暴力解法、快速幂(二进制)、快速幂(指数折半)快速幂于库函数中pow()的区别。进行如下题目练习,以达到掌握目的:数的次幂(基础)->小数第n位(进阶)->堆的计数(综合)->乘法逆元(拓展)三、用法:快速幂可有 2025年全国CTF夺旗赛-从零基础入门到竞赛,看这一篇就稳了! 白帽安全-黑客4148 网络安全web安全linux密码学CTF 目录一、CTF简介二、CTF竞赛模式三、CTF各大题型简介四、CTF学习路线4.1、初期1、html+css+js(2-3天)2、apache+php(4-5天)3、mysql(2-3天)4、python(2-3天)5、burpsuite(1-2天)4.2、中期1、SQL注入(7-8天)2、文件上传(7-8天)3、其他漏洞(14-15天)4.3、后期五、CTF学习资源5.1、CTF赛题复现平台5. 焦点、光标位置、鼠标位置 区别 云中飞鸿--**峰 MFC 一、焦点:光标被激活的位置光标位置:小竖线/横线的位置现在大部分的光标都为一个小竖线,规则的闪动;而在DOS下有些光标则是短短的小横线,同样规则的闪动;现用的windows光标是一个图像,可以是动态的也可以是静态的,在不同情况下样子也不同。鼠标位置:移动鼠标停下时的所在坐标位置二、焦点概述当我们点击了一个编辑框,这个编辑框控件获得了焦点,光标随意移动,只要我们没有点击别的地方,这个编辑框控件就一直 CentOS 7 企业级Redis 7部署指南 去看日出 linuxJAVARediscentosredislinux CentOS7企业级Redis7部署指南目录导航一、环境准备1.1依赖管理二、离线安装2.1源码编译安装2.2目录结构规范三、生产配置3.1主配置文件3.2配置生成脚本四、系统集成4.1Systemd服务文件4.2服务管理命令五、安全加固5.1网络安全配置5.2审计配置六、性能调优6.1内存优化配置6.2基准测试命令七、维护指南7.1监控命令7.2备份策略##一、环境准备###1.1依赖管理安装依 【Python爬虫(12)】正则表达式:Python爬虫的进阶利刃 奔跑吧邓邓子 Python爬虫python爬虫正则表达式进阶高级 【Python爬虫】专栏简介:本专栏是Python爬虫领域的集大成之作,共100章节。从Python基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取,还涉及数据处理与分析。无论是新手小白还是进阶开发者,都能从中汲取知识,助力掌握爬虫核心技能,开拓技术视野。目录一、引言二、正则表达式高级语法详解2.1分组(Grouping)2 通俗理解 CAD CAM CAE 七贤岭双花红棍 c++ CAD、CAM和CAE是工程设计和制造领域中常用的三种技术,它们分别代表不同的功能和应用场景。下面用通俗的语言来解释它们:1.CAD(计算机辅助设计,Computer-AidedDesign)通俗理解:CAD就像是用电脑画图的工具,但它比手绘更精确、更高效。设计师可以用CAD软件在电脑上绘制产品的三维模型或二维图纸,比如设计一个手机外壳、一座桥梁或一辆汽车。作用:帮助工程师和设计师快速创建、修改和 QBarLegendMarker Class Reference 七贤岭双花红棍 c++ QBarLegendMarker是Qt框架中用于条形图(BarChart)图例标记的类,通常与QChart和QBarSeries结合使用。它用于在图表图例中显示条形图的颜色和标签信息。以下是对QBarLegendMarker的详细中文解析,以及一个完整的运行示例。1.QBarLegendMarker类详解(1)类的作用QBarLegendMarker是QLegendMarker的子类,专门用于条形 《Qt+PCL》1.1、点云读取显示 钟某某人 Qt+PCLqt开发语言c++ 文章目录@[TOC](文章目录)前言一、主要流程二、使用步骤1.Qt设置-添加pcl依赖库2.ui界面布局3.添加Qt基本头文件4.添加pcl相关头文件+定义ui界面的元素5.初始化控件6.主函数增加菜单栏7.菜单栏信号与槽设置.8.添加函数功能9.建立信号与槽连接,在初始化函数中添加槽函数链接总结前言在Qt中实现PCL点云数据读取,Qt小白,仅做学习记录,欢迎学习交流指导。一、主要流程1.Qt设 Qt添加链接库总结 糯米藕片 经验分享qt开发语言 Qt添加链接库总结一前言:在Qt工程开发过程中,经常会碰到集成第三方库的情况,不论是静态库还是动态库。由于Qt本身不完善等特性,集成过程中经常会出现各种各样的问题。针对遇到过的问题记录如下备忘,同时也希望能为更多开发者朋友提供前车之鉴。二基础知识简介:2.1关于lib和dll的区别如下:(1)lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运 【Docker项目实战】使用Docker安装Blossom 笔记应用 江湖有缘 Docker部署项目实战合集docker笔记容器 【Docker项目实战】使用Docker安装Blossom笔记应用一、Blossom介绍1.1Blossom简介1.2主要特点1.3使用场景二、本次实践规划2.1本地环境规划2.2本次实践介绍三、本地环境检查3.1检查Docker服务状态3.2检查Docker版本3.3检查dockercompose版本四、下载Blossom镜像五、部署Blossom应用5.1创建部署目录5.2编辑部署文件5.3创 探索GAMP软件的强大功能:一份详尽的使用说明手册 童韵宽 探索GAMP软件的强大功能:一份详尽的使用说明手册【下载地址】GAMP使用说明手册下载分享GAMP使用说明手册下载本仓库提供了一份名为“GAMP使用说明手册”的资源文件下载项目地址:https://gitcode.com/Open-source-documentation-tutorial/5e3c6项目介绍在技术日新月异的今天,掌握一款功能强大的软件工具对于提升工作效率至关重要。GAMP软件作为 推荐开源项目:基于Kotlin的Android架构框架 翟苹星Trustworthy 推荐开源项目:基于Kotlin的Android架构框架项目地址:https://gitcode.com/gh_mirrors/and/AndroidArchitecture1.项目介绍该项目是一个精心设计的Android应用示例,它遵循了谷歌倡导的Android架构组件原则,旨在提供一个清晰、可维护的代码结构。开发者NazarIvanchuk和RomanHavran共同打造了这一典范,将应用程序划 数字化转型与可持续发展:现代企业战略管理的新趋势 项目开发 战略管理方法是指企业在制定、实施和评估战略过程中所采用的具体步骤和框架。以下是一些常见的战略管理方法:1.经典战略管理方法步骤:○环境分析:通过SWOT、PEST等工具分析内外环境。○战略制定:确定使命、愿景、目标,并选择适合的战略。○战略实施:制定行动计划,分配资源,调整组织结构。○战略评估:通过KPI、平衡计分卡等工具监控和调整战略。2.资源基础观(RBV)●核心:企业通过独特的资源和能力获取 量子计算行业深度研究报告:从理论突破到产业变革 萧十一郎@ 深度研究量子计算 目录一、量子计算行业全景洞察1.1量子计算基本原理1.2量子计算发展历程1.3量子计算发展现状二、量子计算关键技术剖析2.1量子比特技术2.1.1超导量子比特2.1.2离子阱量子比特2.1.3光量子比特2.1.4其他量子比特技术2.2量子纠错技术2.3量子算法研究2.3.1Shor算法2.3.2Grover算法2.3.3其他量子算法三、量子计算产业生态构建3.1量子计算产业链结构3.2产业链上游: 液晶图片、动态GIF取模学习心得 绵山介子推 嵌入式杂项学习心得嵌入式软件学习 一、参考连接:link二、显示一张图片:如果只是想显示一张图片,只需要将此图片转化成.bmp格式的图片,再取模即可。要注意的是显示屏幕的分辨率,如果屏幕的分辨率比图片的分辨率要小,则屏幕上无法显示完全图片,可以修改图片的分辨率以后再进行取模。可以使用windows自带的画图工具先打开要修改的.bmp格式的文件,打开以后再手动修改像素:三、显示动图:如果要显示动图,如果只有一张.bmp格式的图片,可 怎么样才能成为专业的程序员? cocos2d-x小菜 编程PHP 如何要想成为一名专业的程序员?仅仅会写代码是不够的。从团队合作去解决问题到版本控制,你还得具备其他关键技能的工具包。当我们询问相关的专业开发人员,那些必备的关键技能都是什么的时候,下面是我们了解到的情况。 关于如何学习代码,各种声音很多,然后很多人就被误导为成为专业开发人员懂得一门编程语言就够了?!呵呵,就像其他工作一样,光会一个技能那是远远不够的。如果你想要成为 java web开发 高并发处理 BreakingBad javaWeb并发开发处理高 java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,java高负载数据) 一:高并发高负载类网站关注点之数据库 没错,首先是数据库,这是大多数应用所面临的首个SPOF。尤其是Web2.0的应用,数据库的响应是首先要解决的。 一般来说MySQL是最常用的,可能最初是一个mysql主机,当数据增加到100万以上,那么,MySQL的效能急剧下降。常用的优化措施是M-S( mysql批量更新 ekian mysql mysql更新优化: 一版的更新的话都是采用update set的方式,但是如果需要批量更新的话,只能for循环的执行更新。或者采用executeBatch的方式,执行更新。无论哪种方式,性能都不见得多好。 三千多条的更新,需要3分多钟。 查询了批量更新的优化,有说replace into的方式,即: replace into tableName(id,status) values 微软BI(3) 18289753290 微软BI SSIS 1) Q:该列违反了完整性约束错误;已获得 OLE DB 记录。源:“Microsoft SQL Server Native Client 11.0” Hresult: 0x80004005 说明:“不能将值 NULL 插入列 'FZCHID',表 'JRB_EnterpriseCredit.dbo.QYFZCH';列不允许有 Null 值。INSERT 失败。”。 A:一般这类问题的存在是 Java中的List g21121 java List是一个有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。 与 set 不同,列表通常允许重复 读书笔记 永夜-极光 读书笔记 1. K是一家加工厂,需要采购原材料,有A,B,C,D 4家供应商,其中A给出的价格最低,性价比最高,那么假如你是这家企业的采购经理,你会如何决策? 传统决策: A:100%订单 B,C,D:0% &nbs centos 安装 Codeblocks 随便小屋 codeblocks 1.安装gcc,需要c和c++两部分,默认安装下,CentOS不安装编译器的,在终端输入以下命令即可yum install gccyum install gcc-c++ 2.安装gtk2-devel,因为默认已经安装了正式产品需要的支持库,但是没有安装开发所需要的文档.yum install gtk2* 3. 安装wxGTK yum search w 23种设计模式的形象比喻 aijuans 设计模式 1、ABSTRACT FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory 工厂模式:客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如: 开发管理 CheckLists aoyouzi 开发管理 CheckLists 开发管理 CheckLists(23) -使项目组度过完整的生命周期 开发管理 CheckLists(22) -组织项目资源 开发管理 CheckLists(21) -控制项目的范围开发管理 CheckLists(20) -项目利益相关者责任开发管理 CheckLists(19) -选择合适的团队成员开发管理 CheckLists(18) -敏捷开发 Scrum Master 工作开发管理 C js实现切换 百合不是茶 JavaScript栏目切换 js主要功能之一就是实现页面的特效,窗体的切换可以减少页面的大小,被门户网站大量应用思路: 1,先将要显示的设置为display:bisible 否则设为none 2,设置栏目的id ,js获取栏目的id,如果id为Null就设置为显示 3,判断js获取的id名字;再设置是否显示 代码实现: html代码: <di 周鸿祎在360新员工入职培训上的讲话 bijian1013 感悟项目管理人生职场 这篇文章也是最近偶尔看到的,考虑到原博客发布者可能将其删除等原因,也更方便个人查找,特将原文拷贝再发布的。“学东西是为自己的,不要整天以混的姿态来跟公司博弈,就算是混,我觉得你要是能在混的时间里,收获一些别的有利于人生发展的东西,也是不错的,看你怎么把握了”,看了之后,对这句话记忆犹新。 & 前端Web开发的页面效果 Bill_chen htmlWebMicrosoft 1.IE6下png图片的透明显示: <img src="图片地址" border="0" style="Filter.Alpha(Opacity)=数值(100),style=数值(3)"/> 或在<head></head>间加一段JS代码让透明png图片正常显示。 2.<li>标 【JVM五】老年代垃圾回收:并发标记清理GC(CMS GC) bit1129 垃圾回收 CMS概述 并发标记清理垃圾回收(Concurrent Mark and Sweep GC)算法的主要目标是在GC过程中,减少暂停用户线程的次数以及在不得不暂停用户线程的请夸功能,尽可能短的暂停用户线程的时间。这对于交互式应用,比如web应用来说,是非常重要的。 CMS垃圾回收针对新生代和老年代采用不同的策略。相比同吞吐量垃圾回收,它要复杂的多。吞吐量垃圾回收在执 Struts2技术总结 白糖_ struts2 必备jar文件 早在struts2.0.*的时候,struts2的必备jar包需要如下几个: commons-logging-*.jar Apache旗下commons项目的log日志包 freemarker-*.jar Jquery easyui layout应用注意事项 bozch jquery浏览器easyuilayout 在jquery easyui中提供了easyui-layout布局,他的布局比较局限,类似java中GUI的border布局。下面对其使用注意事项作简要介绍: 如果在现有的工程中前台界面均应用了jquery easyui,那么在布局的时候最好应用jquery eaysui的layout布局,否则在表单页面(编辑、查看、添加等等)在不同的浏览器会出 java-拷贝特殊链表:有一个特殊的链表,其中每个节点不但有指向下一个节点的指针pNext,还有一个指向链表中任意节点的指针pRand,如何拷贝这个特殊链表? bylijinnan java public class CopySpecialLinkedList { /** * 题目:有一个特殊的链表,其中每个节点不但有指向下一个节点的指针pNext,还有一个指向链表中任意节点的指针pRand,如何拷贝这个特殊链表? 拷贝pNext指针非常容易,所以题目的难点是如何拷贝pRand指针。 假设原来链表为A1 -> A2 ->... -> An,新拷贝 color Chen.H JavaScripthtmlcss <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <HTML> <HEAD>&nbs [信息与战争]移动通讯与网络 comsci 网络 两个坚持:手机的电池必须可以取下来 光纤不能够入户,只能够到楼宇 建议大家找这本书看看:<& oracle flashback query(闪回查询) daizj oracleflashback queryflashback table 在Oracle 10g中,Flash back家族分为以下成员: Flashback Database Flashback Drop Flashback Table Flashback Query(分Flashback Query,Flashback Version Query,Flashback Transaction Query) 下面介绍一下Flashback Drop 和Flas zeus持久层DAO单元测试 deng520159 单元测试 zeus代码测试正紧张进行中,但由于工作比较忙,但速度比较慢.现在已经完成读写分离单元测试了,现在把几种情况单元测试的例子发出来,希望有人能进出意见,让它走下去. 本文是zeus的dao单元测试: 1.单元测试直接上代码 package com.dengliang.zeus.webdemo.test; import org.junit.Test; import o C语言学习三printf函数和scanf函数学习 dcj3sjt126com cprintfscanflanguage printf函数 /* 2013年3月10日20:42:32 地点:北京潘家园 功能: 目的: 测试%x %X %#x %#X的用法 */ # include <stdio.h> int main(void) { printf("哈哈!\n"); // \n表示换行 int i = 10; printf 那你为什么小时候不好好读书? dcj3sjt126com life dady, 我今天捡到了十块钱, 不过我还给那个人了 good girl! 那个人有没有和你讲thank you啊 没有啦....他拉我的耳朵我才把钱还给他的, 他哪里会和我讲thank you 爸爸, 如果地上有一张5块一张10块你拿哪一张呢.... 当然是拿十块的咯... 爸爸你很笨的, 你不会两张都拿 爸爸为什么上个月那个人来跟你讨钱, 你告诉他没 iptables开放端口 Fanyucai linuxiptables端口 1,找到配置文件 vi /etc/sysconfig/iptables 2,添加端口开放,增加一行,开放18081端口 -A INPUT -m state --state NEW -m tcp -p tcp --dport 18081 -j ACCEPT 3,保存 ESC :wq! 4,重启服务 service iptables Ehcache(05)——缓存的查询 234390216 排序ehcache统计query 缓存的查询 目录 1. 使Cache可查询 1.1 基于Xml配置 1.2 基于代码的配置 2 指定可搜索的属性 2.1 可查询属性类型 2.2 & 通过hashset找到数组中重复的元素 jackyrong hashset 如何在hashset中快速找到重复的元素呢?方法很多,下面是其中一个办法: int[] array = {1,1,2,3,4,5,6,7,8,8}; Set<Integer> set = new HashSet<Integer>(); for(int i = 0 使用ajax和window.history.pushState无刷新改变页面内容和地址栏URL lanrikey history 后退时关闭当前页面 <script type="text/javascript"> jQuery(document).ready(function ($) { if (window.history && window.history.pushState) { 应用程序的通信成本 netkiller.github.com 虚拟机应用服务器陈景峰netkillerneo 应用程序的通信成本 什么是通信 一个程序中两个以上功能相互传递信号或数据叫做通信。 什么是成本 这是是指时间成本与空间成本。 时间就是传递数据所花费的时间。空间是指传递过程耗费容量大小。 都有哪些通信方式 全局变量 线程间通信 共享内存 共享文件 管道 Socket 硬件(串口,USB) 等等 全局变量 全局变量是成本最低通信方法,通过设置 一维数组与二维数组的声明与定义 恋洁e生 二维数组一维数组定义声明初始化 /** * */ package test20111005; /** * @author FlyingFire * @date:2011-11-18 上午04:33:36 * @author :代码整理 * @introduce :一维数组与二维数组的初始化 *summary: */ public c Spring Mybatis独立事务配置 toknowme mybatis 在项目中有很多地方会使用到独立事务,下面以获取主键为例 (1)修改配置文件spring-mybatis.xml <!-- 开启事务支持 --> <tx:annotation-driven transaction-manager="transactionManager" /> &n 更新Anadroid SDK Tooks之后,Eclipse提示No update were found xp9802 eclipse 使用Android SDK Manager 更新了Anadroid SDK Tooks 之后, 打开eclipse提示 This Android SDK requires Android Developer Toolkit version 23.0.0 or above, 点击Check for Updates 检测一会后提示 No update were found 按字母分类: ABCDEFGHIJKLMNOPQRSTUVWXYZ其他