java学习日记(小知识杂记)

1.代码可读性

1
scene.fight(hero,enemy,kongfu,FIST);

改为

1
hero.fight(enemy).with(kongfu).by(FIST);

2.不想被重载的方法加上final修饰

3.Thread的run()方法陷阱

启动线程应该使用thread.start()方法,若写成thread.run()则和一个普通的对象调用一次内部写的run()方法没有区别,而不会启动一个线程

4.减少判断次数

判断一个List是否为空时,我们通常会这样判断

1
2
if(list.size() > 0) return true;
else return false;

它可以直接写为

1
return list.size() > 0;

再如

1
if(list != null){for( ... ){ ... }}

则可改为

1
2
if(list == null) return;
for( ... ){ ... }

5.向上转型后使用的是父类的变量,和继承的方法有所区别

6.数据库操作

a.选择表table1中的第20到30条数据
1
select * form table1 limit 19,11
b.没有数据进行更新,使用insert会报错。可使用replace
1
replace into table1(id,name) value (1,"bill");

7.持有Context导致的内存泄漏问题

如果一个对象持有的Context(比如Activity)的生命周期比这个对象的短,则会引起内存泄漏
点击此处查看相关博客
单例模式详解

  • 饿汉式
  • 懒汉式
  • synchronized保证唯一性 (会导致性能下降)
  • static机制
  • 应该尽量使用ApplicationContext,但对于UI控件,它的Context必须是Activity (Toast除外)

8.ViewPager实现平滑滚动

需要通过反射的方式,把Scroller自定义

  • 用法
1
2
3
ViewPagerScroller viewPagerScroller = new ViewPagerScroller(this,new DecelerateInterpolator(),true);
viewPagerScroller.setScrollDuration(400);
viewPagerScroller.initViewPagerScroll(mainPager);//这个是设置切换过渡时间
  • 实现代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* ViewPager 滚动速度设置
*
*/
public class ViewPagerScroller extends Scroller {
private int mScrollDuration = 2000; // 滑动速度
/**
* 设置速度速度
* @param duration
*/
public void setScrollDuration(int duration){
this.mScrollDuration = duration;
}
public ViewPagerScroller(Context context) {
super(context);
}
public ViewPagerScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
public ViewPagerScroller(Context context, Interpolator interpolator, boolean flywheel) {
super(context, interpolator, flywheel);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
super.startScroll(startX, startY, dx, dy, mScrollDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
super.startScroll(startX, startY, dx, dy, mScrollDuration);
}
public void initViewPagerScroll(ViewPager viewPager) {
try {
Field mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
mScroller.set(viewPager, this);
} catch(Exception e) {
e.printStackTrace();
}
}
}

9. android 4.4 实现沉浸式状态栏

  • 1.xml style文件—–style.xml(v-19)
1
2
3
4
5
6
7
8
9
10
11
12
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="colorPrimary">#3498db</item>
<item name="colorPrimaryDark">#3498db</item>
<item name="colorAccent">#3498db</item>
<item name="android:textColorPrimary">#eeeeee</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
  • 2.然后需要在布局文件根节点设置
1
android:fitsSystemWindows="true"
  • 3.导入开源库
1
compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
  • 4.在MainActivity的onCreate方法中设置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
applyKitKatTranslucency();
/**
* Apply KitKat specific translucency.
*/
private void applyKitKatTranslucency() {
// KitKat translucent navigation/status bar.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setTranslucentStatus(true); //设置透明状态栏
SystemBarTintManager mTintManager = new SystemBarTintManager(this);
mTintManager.setStatusBarTintEnabled(true);
mTintManager.setNavigationBarTintEnabled(true);
mTintManager.setTintColor(0xFF3498db); //设置状态栏颜色
//mTintManager.setTintDrawable(UIElementsHelper.getGeneralActionBarBackground(this));
}
}
@TargetApi(19)
private void setTranslucentStatus(boolean on) {
Window win = getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}

10.可滑动tabs页

ViewPager + RadioGroup

11.Fragment应该在什么地方初始化

Fragment的生命周期

onCreateView返回Fragment 的View,所以这个方法返回的越快越好,一般耗时的事情都放在onCreateView以后,至于findViewById啥的一般放在onActivityCreated中

12.Fragment和v4包中的Fragment的区别

  • Fragment支持3.0之后的版本,android.support.v4.app.Fragment可兼容到1.6
  • 当v4.fragment使用标签的时,当这个Activity的布局中有标签的时候,这个Activity必须继承FragmentActivity
  • 如果要使用FragmentManager,必须使用getSupportFragmentManager()
  • 对于使用标签的,sdk版本在14以上的要用getFragmentManager(),而在14一下的可以用getSupportFragmentManager()

13.PhotoView和ViewPager缩放溢出bug

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//这个bug是android ViewPager 自己的问题,解决方案如下
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
return super.onInterceptTouchEvent(ev);
} catch (Exception e) {
// ignore it
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
try {
return super.onTouchEvent(ev);
} catch (IllegalArgumentException ex) {
// ignore it
}
return false;
}

14.Toolbar使用

  • Activity需要继承自AppCompatActivity
  • 设置显示小箭头

    setSupportActionBar(toolbar);
    getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);

  • 设置小箭头的事件

1
2
3
4
5
6
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
  • Android-ObservableScrollView (github上的开源库)

15.不用注解绑定id

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private SparseArray<View> mViews = new SparseArray<>();
public <T extends View> T bindView(int id){
T view = (T) mViews.get(id);
if(view == null){
view = (T) findViewById(id);
mViews.put(id,view);
}
return view;
}
public <T extends View> T get(int id){
return (T)bindView(id);
}
public void setOnClickListener(View.OnClickListener listener,int... ids){
if(ids == null) return;
for(int id : ids){
get(id).setOnClickListener(listener);
}
}

16.fragment点击穿透问题

  • 1.在xml fragment的包裹容器中设置 android:clickable=”true”,可能会导致其它的不可点击的情况
  • 2.Fragment实现View.OnTouchListener接口,设置根部局的触摸事件,重写onTouch方法->return true;(阻止事件传递)

17. Android Service及IPC通信

Service有两种,本地服务和远程服务,本地服务运行在同一进程中,远程服务运行在不同服务中

开启Service有两种方式,startService()和bindService()。
当Client调用startService()后,Client和Service并没有关联,其结束也要通过stopSelf()结束(或是stopService()方法);而Client调用bindService()后,二者相互关联,它们通过Binder的代理对象进行交互,结束服务调用unBindService()断开关联即可。

AIDL(Android Interface Definition Language)是一种IDL语言,用于生成可在两个进程间通信的代码。AIDL面向接口,其用于约束两个进程间的通讯规则,供编译器生成代码,进程间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转成相应的对象(信息经过了双向转换,代理类由编译器生成)