Android群英传笔记
Chapter1 Android体系与系统架构
Android 高富帅 Google Linux Open Source
四层:Applications/Application Framework/Libraries+Android Runtime/Linux Kernel
Android 5.X起ART取代Dalvik Dalvik运行时编译 ART安装时编译
PackageManager/ResourceManager/ActivityManager/WindowManager/ViewSystem/NotificationManager/LocationManager/TelphonyManager/Content Provider/XMPP Service
Android NDK APP AndroidManifest/Dalvik Classes/Resource Bundle/Libraries & JNI
Android SDK APP AndroidManifest/Dalvik Classes/Resource Bundle
四大组件:Activity/BroadcastReceiver/ContentProvider/Service
Intent信使
上下文Context:Application/Activity/Service都继承自Context ApplicationContext是全局的上下文 getApplicationContext()
Android系统源码:http://androidxref.com/ Makefile机制
/system /data目录
/system/app/ 系统APP /system/bin/ Linux自带组件 /system/build.prop 系统属性文件 /system/fonts/ 字体库 /system/framework/ 核心文件框架层 /system/lib/ 节享库.so /system/media/ 提示音系统铃声 /system/usr 用户配置
/data/app/ 用户安装的app /data/data/ App的数据信息 /data/system/ 手机的各项系统信息 /data/misc Wi-Fi/VPN信息
Project/Module
app
--manifests
----AndroidManifest.xml
--java
----com.test.HelloWorld
----com.test.HelloWorld(test)
----com.test.HelloWorld(Android Test)
--res
Gradle Scripts
Chapter2 Android开发工具新接触
工欲善其事,必先利其器
IDE Integrated Development Environment 集成开发环境
Eclipse vs Android Studio(2013年I/O大会)
http://www.androiddevtools.cn
Case sensitive completion
ADB命令
adb version
adb install -r F:\test.apk
adb push D:\test.apk /system/app/
adb push
adb pull
adb shell
adb remount
adb shell
rm *.apk
adb shell input keyevent 3
adb shell input touchscreen
adb shell input touchscreen swipe
pm/am
adb命令来源于\system\core\toolbox 和 \frameworks\base\cmds
Chapter3 Android控件架构与自定义控件详解
Android中每个控件都会在界面中占得一块矩形区域 ViewParent-ViewGroup/View 树形结构
findViewById()深度优先遍历 setContentView()
Activity(PhoneWindow(DecorView(TitleView+ContentView))) 其中DecorView为根View WindowManagerService接收所有View的监听事件
ContentView是一个id为content的FrameLayout TitleView一般为ActionBar Container requestWindowFeature(Window.FEATURE_NO_TITLE)要在setContentView()之前
ActivityManagerService进行Activity的生命周期回调
View的测量:onMeasure()
MeasureSpec是一个32位的int值 高2位为测量模式 低30位为测量的大小
测量模式:
EXACTLY 适用于 android:layout_width="100"或者match_parent
AT_MOST 适用于wrap_content
UNSPECIFIED 适用于自定义View时 想多大就多大
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
//super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
private int measureWidth(int measureSpec){
int result = 100;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if(specMode == MeasureSpec.EXACTLY){
result = specSize;
}else if(specMode == MeasureSpec.AT_MOST){
result = Math.min(result, specSize);
}
return result;
}
View的绘制:onDraw()
Canvas对象 其它地方Canvas canvas = new Canvas(bitmap); canvas.drawXXX();
ViewGroup的测量:遍历子View
ViewGroup的绘制:dispatchDraw()
自定义View:扩展现有控件/组合实现控件/重写View实现
onFinishInflate()/onSizeChanged()/onMeasure()/onLayout()/onDraw()/onTouchEvent()
定义属性:res/values/attrs.xml
string|dimension|reference|color|boolean|enum
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TopBar);
ta.recycle();
xmlns:custom="http://schemas.android.com/apk/res-auto"
重绘:invalidate();/postInvalidateDelayed(300);
自定义ViewGroup:int count = getChildCount(); View childView = getChildAt(i);
事件拦截处理机制
MotionEvent ACTION_DOWN ACTION_MOVE ACTION_UP
public boolean dispatchTouchEvent(MotionEvent ev);
public boolean onInterceptTouchEvent(MotionEvent ev);//View没有此方法
public boolean onTouchEvent(MotionEvent ev);
流程:Adispatch->Aintercept->Bdispatch->Bintercept->Viewdispatch->ViewonTouch->BonTouch->AouTouch
谁拦截谁处理,处理完就回调
Chapter4 ListView使用技巧
public class DataAdapter extends BaseAdapter{
private ArrayList
private LayoutInflater mInflater;
public DataAdapter(Context context){
mDatas = new ArrayList<>();
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount(){return mDatas.size();}
@Override
public Object getItem(int position){return mData.get(position);}
@Override
public long getItemId(int position){return position;}
@Override
public View getView(int position, View convertView, ViewGroup ){
ViewHolder holder = null;
if(convertView == null){
convertView = mInflater.inflate(R.layout.item_content, null);
holder = new ViewHolder();
holder.content = (TextView)convertView.findViewById(R.id.content);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.content.setText("use ViewHolder cache");
return convertView;
}
public final class ViewHolder{
public TextView content;
}
}
设置分隔线:android:divider="@android:color/darker_grey" android:dividerHeight="10dp"
隐藏分隔线:android:divider="@null"
隐藏滚动条:android:scrollbars="none"
取消Item的点击效果:android:listSelector="#00000000" 或 android:listSelector="@android:color/transparent"
显示在第几项:listView.setSelection(N);listView.smoothScrollXX();
notifyDataSetChanged();
空ListView可以设置setEmptyView()来显示内容为空时的提示
ListView的滑动监听:GestureDetector/VelocityTracker onTouchListener/onScrollListener
firstVisibleItem/visibleItemCount/totalItemCount
overScrollBy()中maxOverScrollY改为一个数字就可以弹性十足了
自动显示隐藏的ListView
//添加头防止ActionBar引藏了第一个Item
View header = new View(this);
header.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, (int)getResources().getDimension(R.dimen_abc_action_bar_default_height_material)));
mListView.setHeader(header);
mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();//获取最低滑动距离
View.OnTouchListener mOnTouchListener = new View.OnTouchListener(){……};//动画用属性动画
不同布局的ListView
getItemViewType()/getViewTypeCount()
Chapter5 Android Scroll分析
滑动一个View本质上就是移动一个View改变其当前所处位置
Android坐标系:屏幕左上角(0, 0) 右 X正 下 Y正 getLocationOnScreen(int[] location); getRawX()/getRawY()
视图坐标系:相对于父视图 getX()/getY()
MotionEvent ACTION_DOWN/ACTION_UP/ACTION_MOVE/ACTION_CANCEL/ACTION_OUTSIDE/ACTION_POINTER_DOWN/ACTION_POINTER_UP
View提供的获取坐标的方法:getTop()/getLeft()/getRight()/getBottom()
MotionEvent提供的方法:getX()/getY()/getRawX()/getRawY()
实现滑动的八种方法:
layout()/offsetLeftAndRight()和offsetTopAndBottom()/LayoutParams(getLayoutParams()/setLayoutParams)/scrollTo与scrollBy
Scroller/属性动画/ViewDragHelper(说好八种只有七种还有一种,你想想)
Chapter6 Android绘图机制与处理技巧
屏幕大小:屏幕对角线的长度,单位寸,如5.36寸
分辨率:屏幕的像素点数,720*1280指宽有720个像素点高有1280个像素点
PPI:Pixels Per Inch或DPI,Dots Per Inch 对角线像素点数除以屏幕大小
hdpi:240 / 480 X 800
dp/sp
public class DisplayUtil{
public static int px2dip(Context context, float pxValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(pxValue / scale + 0.5f);
}
public static int dip2px(Context context, float dipValue){
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dipValue * scale + 0.5f);
}
public static int px2sp(Context context, float pxValue){
final float fontScale = context.getResources().getDisplayMetrics().density;
return (int)(pxValue / fontScale + 0.5f);
}
public static int sp2px(Context context, float spValue){
final float fontScale = context.getResources().getDisplayMetrics().density;
return (int)(spValue * fontScale + 0.5f);
}
}
//TypedValue类也可以进行转换
protected dp2px(int dp){
return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
protected sp2px(int sp){
return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
}
2D绘图:Canvas/Paint
Android XML绘图:
Canvas.save()//类似保存图层
Canvas.restore()//类似合并图层
Canvas.translate()//平移坐标原点
Canvas.rotate()//翻转坐标原点
saveLayer()/saveLayerAlpha()/restore()/restoreToCount()
Bitmap位图ARGB
色彩矩阵:ColorMatrix 4X5 一维数组存储 矩阵乘法 RGBA 改变系数 改变偏移量
色调:setRotate()/饱和度:setSaturation()/亮度:setScale()
mImageView.setImageBitmap(ImageHelper.handleImageEffect());
paint.setColorFilter(new ColorMatrixColorFilter(imageMatrix));
像素点分析:
bitmap.getPixels(pixels, offset, stride, x, y, width, height);
bitmap.setPixels(newPx, 0, width, 0, 0, width, height);
Android图像处理之图形特效处理Matrix 3x3
Translate/Rotate/Scale/Skew
像素块分析:drawBitmapMesh()
画笔特效处理:PorterDuffXfermode
Shader着色器:BitmapShader/LinearGradient/RadialGradient/SweepGradient/ComposeShader
PathEffect
public class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback, Runnable
surfaceCreated()/surfaceChanged()/surfaceDestroyed()/run()
private SurfaceHolder mHolder;
private Canvas mCanvas;
private boolean isDrawing;
mHolder = this.getHolder();
mHolder.addCallback(this);
mCanvas = mHolder.lockCanvas();
mHolder.unlockCanvasAndPost(mCanvas);
GenymotionChapter7 Android动画机制与使用技巧
Frame Animation(drawable目录里frame.xml)/Tween Animation(anim目录里tween.xml)
Animation框架定义了AlphaAnimation/RotateAnimation/TranslateAnimation/ScaleAnimation四种动画方式和AnimationSet动画集合
AlphaAnimation aa = new AlphaAnimation(0, 1);
aa.setDuration(1000);
//aa.setAnimationListener(new Animation.AnimationListener(){……});
view.startAnimation(aa);
Animator框架AnimatorSet/ObjectAnimator
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 300);
animator.setDuration(300);
animator.start();
//操作对象必须有getter/setter
//translationX/translationY/rotation/rotationX/rotationY/scaleX/scaleY/pivotX/pivotY/x/y/alpha
private static class WrapperView{
private View mTarget;
public WrapperView(View target){
mTarget = target;
}
public int getWidth(){
return mTarget.getLayoutParams().width;
}
public void setWidth(int width){
mTarget.setLayoutParams().width = width;
mTarget.requestLayout();
}
}
WrapperView wrapper = new WrapperView(mButton);
ObjectAnimator.ofInt(wrapper, "width", 500).setDuration(5000).start();
PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX", 300);
PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("translationY", 300);
ObjectAnimator.ofPropertyValuesHolder(view, pvh1, pvh2).setDuration(3000).start();
ObjectAnimator继承自ValueAnimator
ValueAnimator animator = ValueAnimator.ofFloat(0, 100);
animator.setTarget(view);
animator.setDuration(1000).start();
animator.addUpdateListener(new AnimatorUpdateListener(){……});
一个完整的动画具有start repeat end cancel四个过程
animator.addListener(new AnimatorListener(){……});
animator.addListener(new AnimatorListenerAdapter(){……});
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(animator1, animator2, animator3);
set.start();
//playTogether()/playSequentially()/before()/after()
animator目录下animator.xml
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.scalex);
animator.setTarget(mView);
animator.start();
view.animate().alpha(0).y(300).setDuration(1000).widthStartAction(*).withEndAction(*).start();
Android布局动画android:animateLayoutChanges="true"或者LayoutAnimationController
Interpolators插值器 定义动画的变化速率 线性 加速度
自定义动画:实现applyTransformation的逻辑并Override initialize() 主要是Matrix m = t.getMatrix();
SVG矢量动画机制(5.X)Scalable Vector Graphics可伸缩矢量图形 使用XML定义图形 W3C标准
http://editor.medhod.ac/
VectorDrawable/AnimatedVectorDrawable
group-path
android:width="200dp"
android:viewportHeight="100"
android:viewportWidth="100">
android:rotation="0">
android:pathData="M 25 0 a 25 25 0 1, 0 50, 0" />
AnimatedVectorDrawable如同胶水一样连接VectorDrawable和ObjectAnimator
(imageView.getDrawable()).start();开始动画
线图动画 模拟三球仪 轨迹动画
Chapter8 Activity与Activity调用栈分析
setContentView(View);
Running/Paused/Stopped/Killed
onCreate/onStart/onResume/onPause/onStop/onDestroy/onRestart
onSaveInstanceState()/onRestoreInstanceState
A task is a stack of activities.
android:laaunchMode/standard singleTop singleTask singleTop
Intent.FLAG_ACTIVITY_NEW_TASK
Intent.FLAG_ACTIVITY_SINGLE_TOP
Intent.FLAG_ACTIVITY_CLEAR_TOP
Intent.FLAG_ACTIVITY_NO_HISTORY
clearTaskOnLaunch/finishOnTaskLaunch/alwaysRetainTaskState
Chapter9 Android系统信息与安全机制
系统的配置信息:android.os.Build 和 SystemProperty
String board = Build.BOARD;
String os_version = System.getProperty("os.version");
system/build.prop /proc
PM/AM PackageManager/ActivityManager
ActivityInfo封装了和
ServiceInfo封装了
ApplicationInfo封装了
PackageInfo封装了
ResolveInfo封装了
packages.xml文件 /data/system/packages.xml
安全机制五道防线:代码混淆proguard/AndroidManifest文件权限声明检查/数字证书/UID访问权限控制/沙箱隔离
反编译:
apktool/dex2jar/jd-gui/AndroidKiller
Chapter10 Android性能优化
UI优化
VSYNC信号触发刷新16ms一次 60fps
避免Overdraw
View测量、布局、绘制都是通过对View的遍历进行的
Hierarchy Viewer
内存优化
Android应用沙箱机制 LMK
RAM
寄存器:速度最快,程序无法控制
栈:基本类型的数据和对象的引用
堆:new创建的对象和数组 由GC管理
静态存储区:一直存在的数据 如静态数据变量
常量池:JVM为每个装载的类型维护一个常量池
ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
int heapSize = manager.getLargeMemoryClass();
调用System.gc()只是建议系统进行GC但不一定会被采纳
Bitmap优化(常见于OOM):及时回收内存(bitmap.recycle())、图片缓存
任何Java类都将占用大约500字节的内存空间 创建一个类的实例会消耗大约15字节的内存
Lint/Memory Monitor/TraceView/Android Device Monitor/MAT/Dumpsys/
Debug.startMethodTracing("test");
Debug.stopMethodTracing();
Chapter11 搭建云端服务器
BAAS Backend As A Service
StackMob/Parse/Amazon/Kinvey/Bmob/原子云/AVOS Cloud/百度Frontia/华为PowerApp
数据存储 消息推送 文件服务 API分析 应用统计 移动官网等
Chapter12 Android 5.X新特性
Material Design:纸墨光影纸纸、过渡动画、大色块
http://www.google.com/design/#resources
三种默认主题:
@android:style/Theme.Material
@android:style/Theme.Material.Light
@android:style/Theme.Material.Light.DarkActionBar
Color Palette
colorPrimary/colorPrimaryDark/textColorPrimary/navigationBarColor/windowBackground
色调各类:Vibrant/Vibrant dark/Vibrant light/Muted/Muted dark/Muted light
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.test);
Palette.generateAsync(bmp, new Palette.PaletteAsyncListener(){
@Override
public void onGenerated(Palette palette){
Palette.Swatch vibrant = palette.getDarkVibrantSwatch();
getActionBar().setBackgroundDrawable(new ColorDrawable(vibrant.getRgb()));
getWindow().setStatusBarColor(vibrant.getRgb());
}
});
空间坐标系OXYZ
Z = elevation + translationZ
布局中:android:elevation="Xdp"
代码中:view.setTranslation(X);view.animate().translationZ(X);
Tinting
android:tint="@android:color/holo_blue_bright"
android:tintMode="multiply"
Clipping
ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider(){
@Override
public void getOutline(View view, Outline outline){
outline.setOval(0, 0, view.getWidth(), view.getHeight());
}
};
v.setOutlineProvider(viewOutlineProvider);
RecyclerView
public class RecyclerAdapter extends RecyclerView.Adapter
private ArrayList
public RecyclerAdapter(){
mData = new ArrayList<>();
}
private OnItemClickListener itemClickListener;
public void setOnItemClickListener(OnItemClickListener itemClickListener){
this.itemClickListener = itemClickListener;
}
public interface OnItemClickListener{
void onItemClick(View view, int position);
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
pulic TextView textView;
public ViewHolder(View itemView){
super(itemView);
textView = (TextView)itemView;
textView.setOnClickListener(this);
}
@Override
public void onClick(View v){
if(itemClickListener != null){
itemClickListener.onItemClick(v, getPosition());
}
}
}
@Override
public ViewHodler onCreateViewHolder(ViewGroup viewGroup, int i){
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i){
viewHolder.textView.setText(mData.get(i));
}
@Override
public int getItemCount(){
return mData.size();
}
}
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setHasFixedSize(true);
CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
card_view:cardBackgroundColor="@color/cardview_initial_background"
card_view:cardCornerRadius="10dp"
三种Transition类型:进入、退出、共享元素
Activity进入退出:explode/slide/fade
Activities共享元素:changeBounds/changeClipBounds/changeTransform/changeImageTransform
进入退出使用方法:
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());//ActivityA中
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);//B
或者:
getWindow().setEnterTransition(new Explode());//B
getWindow().setExitTransition(new Slide());
共享元素使用方法:
android:transitionName="XXX"
android:transitionName="XXX"
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, /*view, "share"*/Pair.create(view. "share"), Pair.create(fab, "fab")).toBundle());//A
Ripple效果
android:background="?android:attr/selectableItemBackground"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:color="@android:color/holo_blue_bright">
Animator animator = ViewAnimationUtils.createCircularReveal(oval, oval.getWidth()/2, oval.getHeight()/2, oval.getWidth(), 0);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
animator.setDuration(2000);
animator.start();
状态切换动画
StateListAnimator
android:stateListAnimator="@drawable/anim_change"
selector的item中
android:valueTo="360"
android:valueType="floatType"/>
或者:AnimationInflater.loadStateListAnimator();View.setStateListAnimator();
Animated-selector
android:state_checked="true">
android:toId="@+id/state_off">
……
ToolBar
ToolBar mToolBar = (ToolBar)findViewById(R.id.toolbar);
mToolBar.setLogo(R.drawable.ic_launcher);
mToolBar.setTitle("主标题");
mToolBar.setSubtitle("副标题");
setSupportActionBar(mToolBar);
DrawerLayout
配合使用
getSupportActionBar().setDisplayHomeAsUpEnable(true);
mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.abc_action_bar_home_description, R.string.abc_action_bar_home_description_format);
mDrawerToogle.syncState();
mDrawerLayout.setDrawerListener(mDrawerToggle);
基本Notification
NotificationBuilder builder = new NotificationBuilder(this);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentIntent(pi);
builder.setContentTitle("test");
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(520, builder.build());
折叠Notification
RemoteViews contentView = new RemoteViews(getPackageame(), R.layout.notification);
contentView.setTextViewText(R.id.textView, "show me when collapsed");
notification.contentView = contentView;
RemoteViews expandedView = new RemoteViews(getPackageName(), R.layout.notification_expanded);
notification.bigContentView = expandedView;
悬挂Notification
builder.setContentText("test").setFullScreenIntent(pendingIntent, true);
不同等级
VISIBILITY_PRIVATE//没有锁屏时
VISIBILITY_PUBLIC//任何时候
VISIBILITY_SECRET//没有PIN和PASSWORD等的情况下
builder.setVisibility(Notification.VISIBILITY_PUBLIC);
builder.setColor(Color.CYAN);
builder.setCategory(Notification.CATEGORY_MESSAGE);
更多相关文章
- Android(4.4)音频系统之mediaserver服务启动
- Android之自定义View:点赞动画效果
- Android各代码层获取系统时间的方法
- Android rom开发:不显示系统的电池信息
- Android——调用系统相册
- android获取系统设置的铃声并播放
- android 获取本应用详细系统参数
- android 向系统通讯录添加一个联系人信息