您的位置:首页 > 移动开发 > Android开发

android notes

2016-02-19 12:43 429 查看
持续更新中......

########################################################################################################################

pid uid

############################################################

内存管理

############################################################

JNI

/mtp/MTPJNIInterface.java
1)先声明
private native void testMtpCommands(int opCode, int transactionId);//有native关键词
2)调用
testMtpCommands();

/mtp_jni.cpp
3)
static JNINativeMethod gMTPRawContentMethods[] =
{
{"testMtpCommands","(II)V", (void *)Java_android_mtp_nativetestMptCommands},
....
{"java 函数名","参数",jni接口},
...
{"objectPlaRemoved","(Ljava/lang/String;)V", (void *)Java_android_mtp_nativePlaObjectRemovedCommands}
};

详解JNI -- 
1)结构体
typedef struct {
const char* name; //jni的名字
const char* signature; //参数,
void* fnPtr;
} JNINativeMethod;

参数格式
"()V"
"(II)V"
"(Ljava/lang/String;Ljava/lang/String;)V"
实际上这些字符是与函数的参数类型一一对应的。
"()" 中的字符表示参数,后面的则代表返回值。例如"()V" 就表示void Func();
"(II)V" 表示 void Func(int, int);
具体的每一个字符的对应关系如下
字符 Java类型 C类型
V      void            void
Z       jboolean     boolean
I        jint              int
J       jlong            long
D      jdouble       double
F      jfloat            float
B      jbyte            byte
C      jchar           char
S      jshort          short

数组则以"["开始,用两个字符表示
[I       jintArray      int[]
[F     jfloatArray    float[]
[B     jbyteArray    byte[]
[C    jcharArray    char[]
[S    jshortArray   short[]
[D    jdoubleArray double[]
[J     jlongArray     long[]
[Z    jbooleanArray boolean[]
上面的都是基本类型。如果Java函数的参数是class,则以"L"开头,以";"结尾中间是用"/" 隔开的包及类名。而其对应的C函数名的参数则为jobject. 一个例外是String类,其对应的类为jstring
Ljava/lang/String; String jstring
Ljava/net/Socket; Socket jobject
如果JAVA函数位于一个嵌入类,则用$作为类名间的分隔符。
例如 "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z"

2、JNI 调用java
JNIEnv *env = NULL ;
JavaVM* vm = AndroidRuntime::getJavaVM();
vm->AttachCurrentThread(&env, NULL);
jclass cls = env->GetObjectClass(gInterfaceObject);
jmethodID mid = env->GetMethodID(cls, "getObjectHandle", "(Ljava/lang/String;I)I"); // jni调用java层的getObjectHandle函数。

############################################################

多线程,multithread

############################################################

SurfaceFlinger

############################################################

二、sevicermanager, activitymanager,packagemanager,WindowManagerService
&sevicermanager

&ActivityManagerservice
IActivityManager就是AIDL的Interface.

&packagemanagerservice
packages.xml//记录apk信息
(java)installer -> (c)installd //安装apk的
PackageParser:解析apk,分析其AndroidManifest.xml得到package的各种信息
AppDirObserver
监控system/framework、system/app、data/app等安装目录,inotify
handler//处理安装请求
scanDirLI//apk解析
&WindowManagerService

&PowerManagerService

systemserver.java &location&Alarm&Display&Account&Bluetooth&Input&VR&Cover&Search&xxxManagerService

########################################################################################################################

一、进程间通信
Activity 和broadCast 其实都用了Intent 类,一个是代码中显示用,一个是xml隐式用。
1、Activity-跨进程调用,startActivity(Intent)。 B call A
(1)首先,A share Activity. AndroidManifest.xml <action>
2、content provider相当于SMP,Cursor,
3、broadcast - intent
4、Service -AIDL,binder, handler message,是在binder上的实现,这就是个service

############################################################

一、Manifest.xml
1、

2、
3、
4、
5、注册多个activity

二、layout

#if
1、Android的五大布局分别是LinearLayout(线性布局)、FrameLayout(单帧布局)、RelativeLayout(相对布局)、
AbsoluteLayout(绝对布局)和TableLayout(表格布局)。

linearlayout
(1)android:orientation="vertical" -- 当前lay内,成员排列方式,只有vertical horizontal两种排列
(2)AutoCompleteTextView是自动完成输入内容控件
(3)android:id="@+id/cccxcc"//增加一个id,资源id动态获取,配合(AutoCompleteTextView) findViewById(R.id.cccxcc);使用
(4)类放在layout里面    <com.bn.lccx.GGViewCX
android:layout_width="fill_parent"
android:layout_height="130dp" />
(5)内部类 layout声明 <view
class="com.andorid.Activity$egView"
android:id="@+id/egview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

FrameLayout
(1) 默认位于左上角,,可以通过设置gravity 调整位置
(2)
(3)
(4)
(5)

RelativeLayout
(1) 相对布局,当前view在另一个view的什么位置
(2)
(3)
(4)
(5)

TableLayout / fragementlayout
(1) TableTow 是horizontal 的LinearLayout
(2)
(3)
(4)
(5)

2、autolink
 自动识别链接:

     <!-- android:autoLink="web"-设置自动识别链接,值web为匹配Web网址 -->

     <!--android:autoLink="phone"-设置自动识别链接,值phone为匹配电话号码 -->

     <!-- android:autoLink="email"-设置自动识别链接,值email为匹配Email地址 -->

     <!-- android:autoLink="all"-设置自动识别链接,值all为匹配所有 -->
android:textColorLink="" //链接文字的颜色

3、LayoutInflater -- 扩充layout
作用: 
1)对于一个没有被载入或者想要动态载入的界面, 都需要使用inflate来载入. 
2)对于一个已经载入的Activity, 就可以使用实现了这个Activiyt的的findViewById方法来获得其中的界面元素. 

事先写好的布局文件如果不能满足的需求,有时会根据情况在代码中自定义控件,这就需要用到LayoutInflater。
LayoutInflater经常在BaseAdapter的getView方法中用到,用来获取整个View并返回

第一种方法:
LayoutInflater inflater = LayoutInflater.from(this);  
View layout = inflater.inflate(R.layout.main, null);  

第二种方法:
LayoutInflater inflater = getLayoutInflater();  
View layout = inflater.inflate(R.layout.main, null);  

第三种方法:
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);  
View layout = inflater.inflate(R.layout.main, null);  //第一个参数是新加入的layout

4、dip\px\dp\sp
像素用dp
字体用sp

5、进度条/加载环/loading
<ProgressBar
       android:layout_gravity="center_vertical"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       style="?android:attr/progressBarStyleSmall"
       >
   </ProgressBar>

6、tablayout //TabActivity 被 FragmentActivity 取代了

1cec1
7、res/anim //设置动画效果
(1)popup_enter.xml
/*<set xmlns:android="http://schemas.android.com/apk/res/android">  
<translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="200" />  
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="1000" />  
</set>*/
(2)PopupAnimation.xml
/*<style name="PopupAnimation" parent="android:Animation"> 
<item name="android:windowEnterAnimation">@anim/popup_enter</item>  
<item name="android:windowExitAnimation">@anim/popup_exit</item>   
</style>  */
(3)int aniTabMenu = R.style.PopupAnimation;
(4)this.setAnimationStyle(aniTabMenu);

layout_weight : 默认为0,每个元素按weight比例瓜分父类view的剩余空间。
android:background="#00000000";//半透明<#e0000000>透明<#00000000>半透明<#e0000000>透明<#00000000>,用于一级view,子view中不起作用
android:Alpha="0";//0->1 透明到不透明,用于子view,在第一级view不起作用
android:padding 与 android:layout_margin区别???
padding是在父view角度描述??与所在的view边界距离
margin是与上一个view的距离

#endif

三、语法

#if
1、import static com.xxx.xxx.*; //导入xxx类的static方法。static不需要new实例化,参见《java学习笔记_lmy.java》

#endif

四、view--界面--窗口

#if
1、全屏
android开发中经常会在setContentView(R.layout.XXX); 前设置requestWindowFeature(XXXX)。
他的意思是需要软件全屏显示、自定义标题(使用按钮等控件)和其他的需求
requestWindowFeature(Window.FEATURE_NO_TITLE);//去标题
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
2、界面跳转
setContentView(R.layout.main);

3、SurfaceView implements SurfaceHolder.Callback 
整个过程:继承 SurfaceView 并实现 SurfaceHolder.Callback 接口 ----> SurfaceView.getHolder()获得 SurfaceHolder 对象 
---->SurfaceHolder.addCallback(callback)添加回调函数---->SurfaceHolder.lockCanvas()获得 Canvas 对象并锁定画布
----> Canvas 绘画 ---->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。

callback的接口:
surfaceCreated(holder),surface创建后会立即调用此函数。这里一般做简单的初始化,最后新建一个Thread来绘画内容。
surfaceChanged(holder,format,width,height),当surface状态,大小,格式,发生变化的时候。create会调用一次这个函数。
SurfaceHolder:
SurfaceView的getHolder()函数可以获取SurfaceHolder对象,Surface 就在SurfaceHolder对象内

canvas = lockCanvas(null)
- 获取整个surface,有编辑权限.Rect dirty,更新rect 内的区域,同时,*** rect以外的部分会保留 ***
unlockCanvasAndPost(canvas) - surfaceview 内容映射到lcd,本身内容消失,所以再次lockCanvas所有元素需要全部再画一遍,?????
有一个例外,如果lockCanvas(Rect dirty)设置了 dirty rectangle,只修改dirty内的内容,dirty以外保留,不会消失。

双缓存:三缓存 ???
1)SurfaceView 实例化的时候,cach1,cach2都空,全黑。

什么是双缓存:先生成一个位图,将元素全部绘制到位图上,一次性将位图画到屏幕 -- 不要直接在屏幕上画图,而是将所有的绘图工作先绘制到图片上。
//不用画布,直接在窗口上进行绘图叫做无缓冲绘图,用了一个画布,将所有内容都先画到画布上,在整体绘制到窗口上,就该叫做单缓冲绘
//图,那个画布就是一个缓冲区。用了两个画布,一个进行临时的绘图,一个进行最终的绘图,这样就叫做双缓冲绘图。
###########
View 在UI主线程更新画面,SurfaceView在新线程更新画面
View 必须在OnDraw 所在的主线程 ?显示动画通常用SurfaceView。
###########

4、获取屏幕大小 长宽 dp
/*import android.app.Activity; //已经过时,新sdk不推荐用,The method getWidth() from the type Display is deprecated
int height = getWindowManager().getDefaultDisplay().getHeight();
int width = getWindowManager().getDefaultDisplay().getWidth();*/
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
int SCREEN_WIDTH = dm.widthPixels;
int SCREEN_HEIGHT = dm.heightPixels;

//canvas.getWidth,canvas.getHeight,大小是实际两倍?
5、setOnClickListener 的添加方法
1)第一种,
1 Button btn = (Button) findViewById(R.id.myButton);
2 btn .setOnClickListener(new View.OnClickListener() {
3         public void onClick(View v) {
4 //do something
5         }
6 });
2)第二种,多个button共用一个listener
1 Button btn = (Button) findViewById(R.id.mybutton);
2 Button btn2 = (Button) findViewById(R.id.mybutton2);
3 btn.setOnClickListener(handler);
4 btn2.setOnClickListener(handler);
5 View.OnClickListener handler = View.OnClickListener() {
6         public void onClick(View v) {
7             switch (v.getId()) {
8                case R.id.mybutton: 
9 //do something
10                break;
11                case R.id.mybutton2: 
12 //do something
13                break;
14             }
15   }
16 }
3)第三种,直接将Clicklistener捆绑XML layout中的Views元素
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="@+id/text"
android:text="@string/hello" />
<Button android:id="@+id/mybutton" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:onClick="mybuttonlistener"></Button>
</LinearLayout>

6、android.view.Menu;
1)创建步骤
(1) 覆盖Activity的onCreateOptionsMenu(Menu menu)函数
(2) 调用menu的add()方法添加菜单项(MenuItem),可以调用MenuItem的setIcon()方法来为菜单设置图标
(3) 当菜单项()被选择时,我们可以通过覆盖Activity的onOptionsItemSeleted()方法来响应事件
(4)
(5)
2)xml方法创建
getMenuInflater().inflate(R.menu.main, menu);
7、Toast
1)默认效果:
Toast.makeText(getApplicationContext(), "默认Toast样式",
Toast.LENGTH_SHORT).show();

2)自定义显示位置效果:
toast = Toast.makeText(getApplicationContext(),
"自定义位置Toast", Toast.LENGTH_LONG);
  toast.setGravity(Gravity.CENTER, 0, 0);
  toast.show();

3)带图片效果:
toast = Toast.makeText(getApplicationContext(),
"带图片的Toast", Toast.LENGTH_LONG);
  toast.setGravity(Gravity.CENTER, 0, 0);
  LinearLayout toastView = (LinearLayout) toast.getView();
  ImageView imageCodeProject = new ImageView(getApplicationContext());
  imageCodeProject.setImageResource(R.drawable.icon);
  toastView.addView(imageCodeProject, 0);
  toast.show();

4)完全自定义效果:
LayoutInflater inflater = getLayoutInflater();
  View layout = inflater.inflate(R.layout.custom,
(ViewGroup) findViewById(R.id.llToast));
  ImageView image = (ImageView) layout
.findViewById(R.id.tvImageToast);
  image.setImageResource(R.drawable.icon);
  TextView title = (TextView) layout.findViewById(R.id.tvTitleToast);
  title.setText("Attention");
  TextView text = (TextView) layout.findViewById(R.id.tvTextToast);
  text.setText("完全自定义Toast");
  toast = new Toast(getApplicationContext());
  toast.setGravity(Gravity.RIGHT | Gravity.TOP, 12, 40);
  toast.setDuration(Toast.LENGTH_LONG);
  toast.setView(layout);
  toast.show();

5)其他线程:
new Thread(new Runnable() {
public void run() {
showToast();
}
  }).start();

-------------------------原理分析
1)viewgroup是view的子类,包含多个viewgroup或者view
2)窗口系统是c/s模式,client - View,Viewgroup,DecorView,ViewRoot
3) DecorView 是主view top-level view
4)ViewRoot 建立了主view(DecorView)与窗口系统Server端的桥梁,viewroot是handler的子类
5)绘制流程
performTraversals@viewroot.java
按照视图树的顺序执行,视图绘制时会先绘制子控件。如果视图的背景可见,视图会在调用onDraw函数
之前绘制背景。强制重绘,可以使用invalidate()。
事件的基本流程如下:

         1、事件分配给相应视图,视图处理它,并通知相关监听器。

         2、操作过程中如果发生视图的尺寸变化,则该视图用调用requestLayout()方法,向父控件请求再次布局。

         3、操作过程中如果发生视图的外观变化,则该视图用调用invalidate()方法,请求重绘。

         4、如果requestLayout()或invalidate()有一个被调用,框架会对视图树进行相关的测量、布局和绘制。

        注意,视图树是单线程操作,直接调用其它视图的方法必须要在UI线程里。跨线程的操作必须使用句柄Handler。
##可简单概况为
根据之前设置的状态,判断是否需要重新计算视图大小(measure)、是否重新需要安置视图的位置(layout)、以及是否需要重绘
(draw)

6)IWindowSession getWindowSession() -- 

7) 

8) bitmap

9)canvas bitmap画图过程
(1)获取位图
首先需要获取资源:Resources res=getResources();
使用BitmapDrawable 或者 BitmapFactory获取资源位图
1、BitmapDrawable
a.使用BitmapDrawable(InputStream is) 构造一个BitmapDrawable
b.使用BitmapDrawble getBitmap()方法获取位图
2、BitmapFactory
Bitmap bmp = BitmapFactory.decodeResource(res,R.drawable.pic180);
(2)获取位图信息
大小,像素,density,透明度。
RGB颜色--使用Bitmap.Config 定义,仅包括ALPHA_8、ARGB_4444、ARGB_8888、RGB_565
Bitmap还提供了compress()接口来压缩图片,不过AndroidSAK只支持PNG、JPG格式的压缩;
(3)显示位图
显示位图可以使用核心类Canvas,通过Canvas类的 drawBitmap()显示位图,或者借助于 BitmapDrawable 来将Bitmap绘制到Canvas。
当然,也可以通过BitmapDrawable将位图显示到View中。
canvas.drawBitmap(bmp, 10, 10, null);  
(4)位图缩放
1、将一个位图按照需求重画一遍,画后的位图就是我们需要的了,与位图的显示几乎一样:drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)。
2、在原有位图的基础上,缩放原位图,创建一个新的位图:CreateBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)
3、借助Canvas的scale(float sx, float sy) (Preconcat the current matrix with the specified scale.),不过要注意此时整个画布都缩放了。
4、借助Matrix:

            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pic180);  

            Matrix matrix=new Matrix();

            matrix.postScale(0.2f, 0.2f);

            Bitmap dstbmp=Bitmap.createBitmap(bmp,0,0,bmp.getWidth(),bmp.getHeight(),matrix,true);

            canvas.drawColor(Color.BLACK);

            canvas.drawBitmap(dstbmp, 10, 10, null);  

// 获取缩放位图
Bitmap bm1 = BitmapFactory.decodeResource(getResources(), R.drawable.icon);//获取位图,创建bitmap
foreImage = Bitmap.createScaledBitmap(bm1, can_w, can_h,false);//缩放获取的位图
(5)位图旋转
同样,位图的旋转也可以借助Matrix或者Canvas来实现。

            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pic180);  

            Matrix matrix=new Matrix();

            matrix.postScale(0.8f, 0.8f);

            matrix.postRotate(45);//多了一个rorate

            Bitmap dstbmp=Bitmap.createBitmap(bmp,0,0,bmp.getWidth(),bmp.getHeight(),matrix,true);

            canvas.drawColor(Color.BLACK); 

            canvas.drawBitmap(dstbmp, 10, 10, null); 
(6)图片水印的生成方法
生成水印的过程。其实分为三个环节:第一,载入原始图片;第二,载入水印图片;第三,保存新的图片。
//create the new blank bitmap  
Bitmap newb = Bitmap.createBitmap( w, h, Config.ARGB_8888 );//创建一个新的和SRC长度宽度一样的位图  
Canvas cv = new Canvas( newb );  
//draw src into  
cv.drawBitmap( src, 0, 0, null );//在 0,0坐标开始画入src  
//draw watermark into  
cv.drawBitmap( watermark, w - ww + 5, h - wh + 5, null );//在src的右下角画入水印  
//save all clip  
cv.save( Canvas.ALL_SAVE_FLAG );//保存  
//store  
cv.restore();//存储  
return newb;  
(7)Canvas的save和restore
save和restore之间,往往夹杂的是对Canvas的特殊操作。
❑ save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。
❑ restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。
10)canvas对象获取
(1)view.onDraw(Canvas cv) //通过参数传递,在onDraw里面使用canvas的draw方法////推荐使用这个
(2)Bitmap bit = Bitmap.createBitmap(width,height,Bitmap.config.ARGB_8888);
(3)Path, Path path = new Path(); //定义一条路径,可以沿着这条路径,drawPath(path,paint)/ 画文字 drawTextOnPath("this xxx",path,10,50,paint);
11)canvas 方法
(1)rotate,逆时针旋转画布
12)清除canvas某个图层 // ???
Paint paint = new Paint();  //只能全部清除

        paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));  

        canvas.drawPaint(paint);  

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC));

invalidate();

//必须是当前的同一个canvas,不能是新new的view类。
xml中的view 可以通过findViewById(xxx)来查找当前的view
13)canvas多个图层

#endif

(四) View 类

#if
ViewGroup

2)Listview //联系人列表
三个元素: 1、ListView 用来展示列表的View;2、adapter 把数据映射到View上的中介;3、数据 -被映射的字符/图片/基本组件

Adapter://这个就是用来连接View和data的
在android的开发中最Adapter 一共可以分为
ArrayAdapter<T>, //View.setAdapter(new ArrayAdapter<String>(this, android.R.layout.xxx, mData));
BaseAdapter, //
CursorAdapter,
HeaderViewListAdapter, 
ResourceCursorAdapter,
SimpleAdapter, //new SimpleAdapter(this,mData,android.R.layout.xxx,new String[]{"title","text"},new int[]{android.R.id.text1,android.R.id.text2}); 
SimpleCursorAdapter,
WrapperListAdapter
软件开发中最常用的有ArrayAdapter<T>, BaseAdapter, SimpleAdapter

setAdapter

getView

创建ListView
Steps:
(1) ListView lv = new ListView(this); //创建一个对象
(2) new adapter(data);
//adpter 和 data 有了
(3) lv.setAdapter(adapter); //

系统要绘制ListView了,他首先获得要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用getView()函数。在这个函数里
面首先获得一个View(实际上是一个ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完这一行了。那 再绘制下一行,直
到绘完为止。在实际的运行过程中会发现listView的每一行没有焦点了,这是因为Button抢夺了listView的焦点,只要布局文件中将Button
设置为没有焦点就OK了。

超出屏幕大小的view,不会画出来,滚动的时候再画。。。。。。
3)ViewHolder //eg. 利用ViewHolder优化自定义Adapter的典型写法
就是一个持有者的类,他里面一般没有方法,只有属性,作用就是一个临时的储存器,把你getView方法中每次返回的View存起来,可
以下次再用。这样做的好处就是不必每次都到布局文件中去拿到你的View,提高了效率
   static class ViewHolder{
CheckBox selected;
TextView name;
TextView address;
} //成员可以随便定义
4)selector 用法 //http://suo.im/ncnt3
Android中的Selector主要是用来改变ListView和Button控件的默认背景。其使用方法可以按一下步骤来设计:
1.创建mylist_view.xml文件,首先在res目录下新建drawable文件夹,再在新建的drawable文件夹中新建mylist_view.xml

5)TextView
(1) 设置文字的阴影
android:shadowColor="@color/green"

            android:shadowRadius="3.0"
(2) 单行显示 -- android:singleLine="true"
(3) 跑马灯效果 -- 
若要让TextView里的文本滚动,必须满足以下几个因素:
1,TextView里文本宽度超过TextView的宽度
2,android:ellipsize="marquee"
3,只有在TextView获取到焦点时,才会滚动.所以加上android:focusableInTouchMode="true" android:focusable="true"
4,android:singleLine="true"
最容易忽略的是第三条.另滚动重复次数设置:android:marqueeRepeatLimit="marquee_forever" //不设forever 只滚动一次
5,遇到的问题,设置autolink="email" 不能滚动
在触摸模式下android:clickable="true"是(android:focusable="true",android:focusableInTouchMode="true")能获得焦点的必要条件,
(4) android:ellipsize="start""middle""end""marquee" //省略号位置
start - 在开头,middle - 在中间,end - 在末尾,默认末尾?
(5) 获取焦点
android:focusable="false" //不能获取焦点
6)ImageView
(1)
(2)
(3)android:scaleType == ImageView.setScaleType() //http://t.cn/zOLKsTc
CENTER /center  按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示
CENTER_CROP / centerCrop  按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长(宽)
CENTER_INSIDE / centerInside  将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽
FIT_CENTER / fitCenter  把图片按比例扩大/缩小到View的宽度,居中显示
FIT_END / fitEnd   把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置
FIT_START / fitStart  把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置
FIT_XY / fitXY  把图片不按比例扩大/缩小到View的大小显示
MATRIX / matrix 用矩阵来绘制
(4)
(5)
(6)
(7)
(8)

7)WindowManager
addView -- 添加悬浮窗
updateViewLayout --更新悬浮窗参数
removeView -- 移除悬浮窗

void android.view.Window.setFlags(int flags, int mask)

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> //在所有view的上面
多个悬浮窗可以共存。是否能同时接受点击???

#endif

五、SQLite

#if
1、CRUD -- create/remove/update/delete
execSQL(insert,delete,update,create table)
rawQuery(select)

SQLiteDatabase sld=createOrOpenDatabase();//连接数据库
2、contentresolver / contentprovider / SQlite关系
首先sqlite是私有的,只能在自己的应用程序进行增删改查,现在呢,我们需要让别的应用程序也能更改这个数据库的数据,我们就用
一个contentprovider把这个数据库的数据封装,这样就可以实现各应用程序共享了,现在回答contentprovider的增删改查和sqlite
中的增删改查有什么关系,因为contentprovider的存储方式是以表的形式存储的,但要存储的数据不一定来源于数据库,所以在contentprovider
中也要实现增删改查的方法,当你要对数据库中数据进行增删改查时,此时你可以绑定到该数据库,调用数据库自己的增删改查方法;
当你要对其他(文件)进行增删改查时,你可以绑定其他。这样就实现了对数据的增删改查。现在回答ContentResoler的增删改查,因为
是各应用程序共享,所以我要在B程序中对A程序中的数据进行更改,我就可以调用ContentResoler的增删改查方法。参数是contentprovider
的URI(类似给数据的来源定义一个路径,像域名),这样就绑定到了A程序的数据了,就可以增删改查了。不知道这样说能否解决你的困惑。

3、Cursor //

Cursor 是每行的集合。
使用 moveToFirst() 定位第一行。
你必须知道每一列的名称。
你必须知道每一列的数据类型。
Cursor 是一个随机的数据源。
所有的数据都是通过下标取得。

在Android 查询数据是通过Cursor 类来实现的。当我们使用 SQLiteDatabase.query()方法时,就会得到Cursor对象, Cursor所指向的就是
每一条数据。

8、效率
1)批量插入,使用事务,可以提升几千倍的效率。

2)单次插入,使用事务方而效率降低

#endif

六、同步
1)ArrayList的同步方法
(1)IsSynchronized ArrayList.Synchronized方法 //返回线程同步的封装
(2) 使用lock ;// lock(list.SyncRoot)

1、synchronized
关键字
对象(方法),防止同时访问,难道就是个互斥锁?
类同步,对类访问互斥。

七、Activity
启动方式,隐式(implicit), 显式(explicit)
启动需要经过三个参数的匹配,<action/><category/><data/>
explicit: Intent intent= new Intent(this, B.class) ;//启动B,明确知道需要启动的activity名字,不想被filter
implicit: intent加action categary data. 通过intentfilter 筛选启动哪个activity。

#if

3)ListActivity

#endif

八、Graphic 类

#if
1、Canvas类

方法
canvas.rotate(sec*360/count, 0, 0); //(float degrees, float px, float py),以(x,y)中心逆时针旋转
//一次OnDraw内,旋转会保持角度,直到ondraw一次运行结束才恢复原角度,下次ondraw再重新旋转。

#endif

九、widget 类

#if
1、ScrollView //垂直
ListView/TestView??? 有自己的滚动方法。

2、HorizontalScrollView //水平
滚动步骤:
1)在layout创建xml,包含HorizontalScrollView类,内部嵌入LinearLayout,id/cont
2)Activity 中,将imageview 加入cont
3)继承创建HorizontalScrollView类,重写onMeasure函数,onMeasure将viewgroup图片放入ArrayList
4)override onTouchEvent, 调用smoothScrollTo(ArrayList,0); //滚动到目标子视图

3、Scroller

4、Popupwindow
(1)final PopupWindow pw= new PopupWindow(vPopupWindow,300,300,true);//PopupWindow(View contentView, int width, int height, boolean focusable)
(2)pw.showAtLocation(parent, Gravity.CENTER, 0, 0);//showAtLocation(View parent, int gravity, int x, int y)

5、Toast
几种类型的Toast
1)默认样式
Toast.makeText(getApplicationContext(),"默认",Toast.LENGTH_SHORT).show();
2)定义位置
toast = Toast.makeText(getApplicationContext(),"位置", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
3)带图片
toast = Toast.makeText(getApplicationContext(),"图片", Toast.LENGTH_LONG);
LinearLayout toastView = (LinearLayout) toast.getView();
ImageView imageCodeProject = new ImageView(getApplicationContext());imageCodeProject.setImageResource(R.drawable.icon);
toastView.addView(imageCodeProject, 0);
toast.show();
4)自定义
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.custom,(ViewGroup) findViewById(R.id.llToast));
toast = new Toast(getApplicationContext());
toast.setView(layout);
toast.show();
5)新线程
new Thread(new Runnable() {
public void run() {
showToast();
}
}).start();

6、SeekBar //可拖动的进度条
1)barActivity implements SeekBar.OnSeekBarChangeListener{}
2)SeekBa mSeekBar.setOnSeekBarChangeListener(this);
3)onProgressChanged() / onStartTrackingTouch() / onStopTracking()

7、ProgressBar
1)layout定义ProgressBar属性,
2)progressbar.setProgress(progress);

8、RatingBar
1)layout定义RatingBar属性
OnRatingBarChangeListener()
2)ratingBar.setRating(progress/MAX*RATING);

9、Tabhost
步骤
1)private TabHost myTabhost=this.getTabHost();
2)LayoutInflater.from(this).inflate(R.layout.main, myTabhost.getTabContentView(), true);
2))or Tabhost added in layout //推荐放在layout
3)myTabhost.addTab(myTabhost.newTabSpec("One")
.setIndicator("A",getResources().getDrawable(R.drawable.gimp))
.setContent(R.id.widget_layout_Blue));
4)myTabhost.setOnTabChangedListener(this);

10、GridView
步骤
1)xml定义GridView,gv=findbyid
2)ImageAdapter ia=new ImageAdapter(GridviewActivity.this, lsmap);//
3)gv.setAdapter(ia);
4)gv.setOnItemClickListener(new ...)

12、BaseAdapter

#endif

十、app 类

#if
0、Activity
1)onCreate
2)onStart
onResume
3)onPause
4)onStop
5)onDestroy //finish();
6)
6)

1、AlertDialog //http://t.cn/SXVryl
android.app.AlertDialog是android.app.Dialog的子类并实现了android.content.DialogInterface接口。支持三个按钮。
1)创建方法/步骤
方法一,自建showdialog函数,showDialogx(Context context)
(1)AlertDialog.Builder builder = new AlertDialog.Builder(context);
(2)builder.setIcon(R.drawable.icon);
builder.setTitle("Title");
builder.setMessage("Message");
(3)builder.setPositiveButton();
(4)builder.show();
方法二,使用父类showDialog(id)方法, eclipse提示不推荐用这个
(1)showDialog(DIALOG_YES_NO_MESSAGE);//-> onCreateDialog(int, Bundle) -> onPrepareDialog(int, Dialog, Bundle)
(2)protected Dialog onCreateDialog(int id) {return new AlertDialog.Builder(MainActivity.this).setxx.setxx.show();}

2、Dialog

4、appwidget
AppWidget框架类
1)AppWidgetProvider:
#继承自BroadcastReceiver,使用update\enable\disable\delete方法,onUpdate(),onReceive()是最常用的方法。
2)AppWidgetProvderInfo(xml文件里面):
#描述AppWidget的大小,更新频率、初始界面。
3)AppWidgetManger:
#负责管理 AppWidget ,向 AppwidgetProvider 发送通知。
* bindAppWidgetId(int appWidgetId, ComponentName provider)//通过给定的ComponentName 绑定appWidgetId
* getAppWidgetIds(ComponentName provider)//通过给定的ComponentName 获取AppWidgetId
* getAppWidgetInfo(int appWidgetId)//通过AppWidgetId 获取 AppWidget 信息
* getInstalledProviders()//返回一个List<AppWidgetProviderInfo>的信息
* getInstance(Context context)//获取 AppWidgetManger 实例使用的上下文对象
* updateAppWidget(int[] appWidgetIds, RemoteViews views)//(ComponentName provider, RemoteViews views)//(int appWidgetId, RemoteViews views)
 通过appWidgetId 对传进来的 RemoteView 进行修改,并重新刷新AppWidget 组件
4)RemoteViews:
#一个可以在其他应用进程中运行的类,向 AppWidgetProvider 发送通知。 

5、Service
运行在主线程,在后台。
1)本地服务 local service. context.startService()启动,context.stopService(intent)停止。
2)远程服务 Remote service. 系统内部应用程序之间。调用Context.bindService()方法建立连接,Context.unbindService()关闭连接。
3)生命周期 Lifecycle  l Context.stopService() or stopSelf() is called
context.startService(new Intent(context, UpdateService.class));

onStartCommand(Intent intent, int flags, int startId)

本地服务步骤:
1)Intent intent = new Intent(MainActivity.this, FloatWindowService.class);
startService(intent); 
2)public class FloatWindowService extends Service,重写onCreate(),onStartCommand()
3)AndroidManifest.xml application内注册 <service android:name=".FloatWindowService"></service> 

进程间服务步骤:
1)
2)
3)
4)

setProcessForeground // 
(IActivityManager)mAm.setProcessForeground(binder , android.os.Process.myPid(), start );//前台进程,不会被销毁

6、ActivityManager
这个类主要用来管理所有设备上的Activities。

7、Fragment
在 activity 中使用 fragment 的一个伟大的好处是能跟据用户的输入对 fragment 进行添加、删除、替换以及执行 其它动作的能力。
提交的一组 fragment 的变化叫做一个事务。事务通过 FragmentTransaction 来执行。还可以把每个 事务保存在 activity 的后退
栈中,这样就可以让用户在 fragment 变化之间导航(跟在 activity 之间导航一样)。
1)
2)Fragment管理
FragmentManager = getFragmentManager();
findFragmentById() / findFragmentByTag() //获取activity已存在的fragment。
popBackStack() //从 activity 的后退栈中弹出 fragment(这可以模拟后退键引发的动作)
addOnBackStackChangedListerner() //注册一个侦听器以监视后退栈的变化
还可以使用 FragmentManager 打开一个 FragmentTransaction 来执行 fragment 的事务,比如添加或删除 fragment。
3)创建步骤

8、FragmentActivity

#end

十一、Timer
1、延时/周期性执行
1)new Timer.schedule(new Task,long t1,long t2);(任务队列,延时执行task,周期ms)//可以将myTask函数体直接放在Task位置
new myTask() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
h.sendEmptyMessage(loop);
}
}
}

if (mTimerTask != null)  mTimerTask.cancel();  //将原任务从队列中移除
mTimerTask = new MyTimerTask();  // 重新新建一个任务
"TimerTask is scheduled already" //http://t.cn/z8L6QJ5    ,只能schedule一次timertask.

十二、框架机制

#if
1、Binder
(1) binder驱动, /dev/binder驱动,
(2) ServiceManager, 管理服务,系统服务对象的管理中心。
(3) Server, 向client提供服务
(4) client,具体的app
(5) proxy,stub
2、AIDL

3、handler
只运行在主线程???一般主线程,谁创建handler,就运行在谁上面
handler分发消息的方法
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)

post类方法排列一个Runnable对象到主线程队列中
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.

Message msg = handler.obtainMessage();//获取当前消息实例?yes, 通过调用obtainMessage方法获取Message对象就能避免创建对象,从而减少内存的开销。

//为当前线程创建looper。
1、HandlerThread thread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND); //创建一个新线程
2、thread.start();
3、private Looper mServiceLooper = threat.getLooper();//获取新线程的looper
4、private mServiceHandler = new ServiceHandler(mServiceLooper);//将新线程的looper给当前线程的handler,looper获取的消息交给handler处理。
创建步骤:
post()
(1) private Handler handler = new Handler();
(2) handler.post(new Runnable() {
@Override
public void run() { xxxx();}
});
sendMessage()
(1) Handler hd=new Handler(){ //匿名类的形式,还可以以内部类来创建
@Override
public void handleMessage(Message){
switch(msg.what){
case 0: break;}}
}
(2) this.hd.sendEmptyMessage(0); //目标activity.this.handler.sendMessage();
内部类 new MyHandler();
class MyHandler extends Handler {@Override public void handleMessage(Message msg)...}
send--handle对应关系,handlerA send,handlerA 处理,handlerB send, handlerB 处理。绝不可能hanlderA发,hanlderB收。

#endif

十三、实用工具
1、AnalogClock / DigitalClock

、实例

#if
1、启动界面图片适配问题。
使用bitmap画启动界面,可以像layout一样指定fill_parent吗?
ANS: layout 就是view类,可以指定,但是最好使用等比缩放适应屏幕。
2、将view 类放进layout,启动时候提示 android.view.InflateException: Binary XML file line #28: Error inflating class com.bn.sample.CanvasView
ANS:放在layout的view必须实现 public XxxView(Context context,AttributeSet attrs){super(context,attrs)} 这个类,否则就有上面的问题。

3、Avoid object allocations during draw/layout operations (preallocate and reuse instead)
onDraw / layout尽量不用new 过程,这里经常调用,比较耗内存,new放在onDraw外面
4、ListView 可以看到表格线,但是看不到内容,点击高亮时可以看到内容? // color issue, change to white solved

5、onMenuOpened 与onCreateOptionsMenu 同时弹出? onCreateOptionsMenu返回true false 都一样???(Popupwindow)
6、Tab TabWidget两个工程,tab大小为什么不一样???
7、Eclipse shift+ctrl+O就是导入全部的包.

#endif

解决方案list--

#if

一、实现图片滚动
1、View 类里面内嵌Scroller 对象方法,使用mScroller.startScroll((int)touchPt.x,(int)touchPt.y,dx,dy,1000);
2、HorizontalScroller,这个类把图片全部加载,作为viewgroup的子视图childView
3、

二、实现view回弹效果
1、继承ScrollView
2、重写onTouchEvent
1)ACTION_DOWN 获取y坐标
2)ACTION_MOVE inner.layout(,TOP-delaT,,bottom-delaY); //移动整个layout
3)ACTION_UP layout回到正常位置 inner.startAnimation(ta);

#endif

////java 学习笔记lmy////////////////////////////////

1、编译

$后面跟数字是匿名类编译出来的 --- xxxx$1.class
$后面跟文字是内部类编译出来的 --- UsbDeviceManager$UsbHandler$1.class

2、语法规则

#if
1)内部类 -- 只能在内部实例化
2)匿名类 -- 
·只用到类的一个实例 。
·类在定义后马上用到。
·类非常小(SUN推荐是在4行代码以下)
实例2:匿名内部类的基本实现
abstract class Person {
//抽象类
public abstract void eat();
}
 
public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println("eat something");
}
};
p.eat();
}
}
运行结果:eat something
3)this 当前实例索引
4)super 父类索引
//都必须放在构造方法的第一行
5)方法的覆盖和重载
6)多态
(父)Employee e= (子)new Manager;
//new谁调用谁的方法
//manager特殊的部分隐藏,调用继承/重写的部分

Manager mana = (Manager)e;就可以调用隐藏的部分了(强制类型转换)

向上类型转换是可以的,可以不需要类型转换符。 向下不可以,但是可以还原new的类型。
------------------
多态:父类型的引用可以指向子类型的对象。
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的该同名方法。
父 fu= new 子;子 zi=new 子;相同,都是访问子方法,子没有再调用父方法,区别,父不能调用子独有的方法,子可以调用父方法。
即,只是限制了父的调用。

多态的意义:统一的接口,实现不同的方法。比如,调用父类 animal.eat(), 牛调用牛的子类方法吃草,狼调用狼的子类方法吃肉,同一个接口,内容不同,结果不同。
直接用子类,那么接口比较乱?
------------------
(1)编译时多态(静态多态)
(设计时多态):方法重载。public void eat(apple ap); public void eat(apple ap, pear p); public eat(a,b,c) --- 即根据参数区分方法,编译器就决定了的。
(2)运行时多态(动态多态)
继承后的多态,父指针,指向哪个是不确定的,比如Father Fa = new apple() ;Fa.eat(apple), --- Father Fa = new pear(); Fa.eat(apple),  虽然都是eat,但是只有运行的
时候才知道调用的是哪个子类的方法。这里说的是是屏蔽子类new过程的,看代码当然知道是调用谁。
参数传递:
a2.show(b);  ,外部先找父类,没有,然后内部再找父类。优先级高于多态,先优先级,在父指子类方法。现在懂了,以后生疏了估计好难懂。http://www.jb51.net/article/34413.htm
优先级由高到低依次为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
返回类型:
如果需要返回,那么方法前面需要加返回的类型名
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
7)instanceof 检查是不是某个子类 e instanceof Manager

instance 单例模式,getinstance,一旦创建对象,就不需要在实例化了
8)static
类中的static变量/方法,不需要new就可以直接访问。同一个包内方法不需要import就可以用。
static 修饰的实例/只有一份内存 //一份内存,多线程调用,有风险
构造不能是static的;

static方法只能访问static变量/方法***
//只要是公用的方法,属性,类常常用到才申明为static其它最好不用,内存用的太多影响其它业务
9)final
(1)类,类不能被继承
(2)方法,不能被重写
(3)变量,即成为常量
(4)成员变量,要么开始就赋值,要么构造里赋值,只赋值一次
(5)局部变量,只赋值一次
10)implements
实现接口的keyword,实现抽象方法。
接口是特殊抽象类,只定义无实现

11)泛型(Generic Type) Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.
Map<String, String> m = new HashMap<String, String>();
<?> //类型通配符
使用泛型只是带来了附加的类型安全。因为编译器知道关于您将放进 Map 中的键和值的类型的更多信息,所以类型检查从执行时挪到了编译时,这会提高可靠性并加快开发速度。

#endif

3、数组

#if
Array //容量固定
定义:
int intArray[];//不用指出数组的大小,刚定义的时候,java也不会给数组分配内存
intArray = new int[3]; // == int intArray[] = new int[3];
引用:
intArray[2]
初始化:
定义的时候初始化;for循环各个初始化

ArrayList 动态数组,可以将 ArrayList想象成一种“会自动扩增容量的Array”。

动态的增加和减少元素//链表?,LinkArray, 是链表,但是没下标。
实现了ICollection和IList接口
灵活的设置数组的大小//每add delete,要移动整个序列,保证下表对应的值正确,这个和LinkArray比劣势
(1)构造器,有三个
public ArrayList(); //default construction,大小16
public ArrayList(ICollection);//用ICollection对象来构建list元素
public ArrayList(int); //指定list大小
(2)同步方法
a、IsSynchronized属性 和 ArrayList.Synchronized方法,方法返回一个线程同步的封装
b、lock(list.SyncRoot);

(3)Count 属性和 Capacity属性
Count 只读,Arraylist的元素数量
Capacity 当前Arraylist的最大容量。
(4)Add, AddRange, Remove, RemoveAt, RemoveRange, Insert, InsertRange
Add -- 添加一个元素到当前列表的末尾
AddRange -- 添加一批元素到当前列表的末尾
Remove -- 删除一个元素,通过元素本身的引用来删除
RemoveAt -- 删除一个,通过索引值来删除
RemoveRange -- 删除一批元素,指定开始索引,删除数量
Insert -- 添加一个元素到指定位置
InsertRange -- 从指定位置开始添加一批元素

Clear -- 清除现有所有的元素
Contains -- 元素是否在list里面
(5)TrimSize -- 固定到ArrayList的实际大小,将多余的空间释放。
(6)ToArray -- 把ArrayList的元素Copy到一个新的数组(Array)中

Question:
1) List<String> data = new ArrayList<>();// Arraylist 可以直接赋值给List?,List是接口,ArrayList是它的实现类。
2) Map<String,Object> map = new HashMap<>();//Map是接口,Map特性就是根据一个对象查找对象.HashMap是它的实现类,HashMap用hash表实现的Map,就是利用对象的hashcode(hashcode()是Object的方法)进行快速散列查找.(关于散列查找,可以参看<<数据结构>>)

#endif

4、String 字符串

#if
String 字符串常量 // String = "this is" + "StringBuffer" ,拼接其实是StringBuilder
StringBuffer 字符串变量(线程安全),线程安全的可变字符序列
StringBuilder 字符串变量(非线程安全),该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)

#endif

4、存储

#if
HashMap
HashMap<String,Double> map = new HashMap<String,Double>();
map.put("chinese", 90);

HashMap 采用hash算法,决定元素存储位置。
HashCode()方法计算“chinese”的hashcode 值,然后根据这个值决定存储位置

#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android notepad++检索