学徒的时候安卓老知识点总结汇总 (新手应该大概了解的)

学徒的时候安卓老知识点总结汇总
(新手应该大概了解的)

 

Linux中的总结

bashrc与profile的区别

要搞清bashrcprofile的区别,首先要弄明白什么是交互式shell和非交互式shell,什么是loginshell 和non-loginshell。

交互式模式就是shell等待你的输入,并且执行你提交的命令。这种模式被称作交互式是因为shell与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。当你签退后,shell也终止了。 shell也可以运行在另外一种模式:非交互式模式。在这种模式下,shell不与你进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾,shell也就终止了。

bashrcprofile都用于保存用户的环境信息,bashrc用于交互式non-loginshell,而profile用于交互式login shell。系统中存在许多bashrcprofile文件,下面逐一介绍:

/etc/pro此文件为系统的每个用户设置环境信息,当第一个用户登录时,该文件被执行.
并从/etc/profile.d目录的配置文件中搜集shell的设置.
/etc/bashrc:为每一个运行bash shell的用户执行此文件.bash shell被打开时,该文件被读取。有些linux版本中的/etc目录下已经没有了bashrc文件。
~/. pro每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,
文件仅仅执行一次!默认情况下,它设置一些环境变量,然后执行用户的.bashrc文件.
~/.bashrc:该文件包含专用于某个用户的bash shellbash信息,当该用户登录时以及每次打开新的shell,该文件被读取.

另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,~/.bashrc等中设定的变量(局部)只能继承/etc/profile中的变量,他们是"父子"关系.

安卓、java的一些基础概念:

android和java的区别

在Android应用程序框架中,包含了很多开源工程,例如浏览器用的内核WebKit、管理Wi-Fi网络的wap_supplicant、播放音乐视 频的StageFright等,它们都是使用C/C++来写的。而且Android系统专用的用来渲染UI的SurfaceFlinger、用来播放声音 的AudioFlinger等,也是用C/C++来写的。更不用提每一个应用程序都要使用到C库bionic、Dalvik虚拟机等了,它们都是用C /C++来写的。这些使用C/C++写的服务,实现了最基本的功能。这些最基本的功能被在Java层的提供的关键服务所使用,例如组件管理服务ActivityManagerService、应用程序安装服务PackageManagerService、网络连接服务 ConnectivityService等。最后,Android再封装了一套基于Java语言的SDK给开发者去使用那些实现在Java层的系统服务。

也就是说:Android系统=Linux内核+Android用户空间运行时+ Android SDK,而Android用户空间运行 时=C/C++ Runtime Framework + Java Runtime Framework。很多情况下,我们调用Android SDK提供的一个API时,这个API调用会交给Java Runtime Framework处理,而Java Runtime Framework又继续将 这个API调用交给C/C++ Runtime Framework处理,最后C/C++ Runtime Framework又有可能接着将这个API 调用交给Linux内核来处理。

JVM、Dalvik和ART

参考:http://www.jianshu.com/p/58f817d176b7

   http://blog.csdn.net/jason0539/article/details/50440669

 

JVM:

之后会介绍;

Dalvik:

它是Google等厂商合作开发的Android移动设备平台的核心组成部分之一。它可以支持已转换为 .dex格式的Java应用程序的运行,.dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。

ART:(Android Runtime)

编译机制和Dalvik不一样。它是预编译,在编译的时候就转化为机器码并存储。而不是等到执行的时候才去编译。

ART VS Dalvik

在4.1的时候,又通过Project Butter计划,极大地提高了UI的流畅性。到了L版本,又用ART(AndroidRunTime)代替了Dalvik,这意味着应用程序运行时执行的是本地机器指令,而不再是虚拟机机指令,性能将得到极大的提升。总之,目前在同等硬件配置下,Android的UI流畅性与iOS相比,差距是越 来越小了。我们期待ART代替Dalvik之后,两者可以不相伯仲。

Dalvik VS JVM

Dalvik是基于寄存器的,而JVM是基于栈的。
Dalvik运行dex文件,而JVM运行java字节码

标准Java字节码实行8位堆栈指令,Dalvik使用16位指令集直接作用于局部变量。局部变量通常来自4位的“虚拟寄存器”区。这样减少了Dalvik的指令计数,提高了翻译速度。

基于栈结构,程序在运行时虚拟机需要频繁的从栈上读取写入数据,这个过程需要更多的指令分派与内存访问次数,会耗费很多CPU时间。

Dalvik虚拟机基于寄存器架构,数据的访问通过寄存器间直接传递,这样的访问方式比基于栈方式要快很多。

Dalvik VM把.java文件编译成.class后,会对.class进行重构。

 

 

线程安全:

参考:http://blog.csdn.net/xiao__gui/article/details/8934832

问:ArrayListVector有什么区别?HashMapHashTable有什么区别?StringBuilderStringBuffer有什么区别?

答:

ArrayList线程安全的,Vector是线程安全的;

HashMap线程安全的,HashTable是线程安全的;

StringBuilder线程安全的,StringBuffer是线程安全的。

1000个线程分别向这个ArrayList里面添加元素,每个线程添加100个元素,等所有线程执行完成后,这个ArrayListsize应该是多少?

如果线程安全的话应该是100000

但是我们打印10次的结果为99946,100000,100000,100000,99998,99959,100000,99975,100000,99996。甚至有时候会排出异常IndexOutOfBoundsException

如果用线程安全的Vetor就是100000。

非线程安全:是指多线程操作同一个对象可能会出现问题。

线程安全:是多线程操作同一个对象不会有问题。

线程安全的弊端:为了保证线程安全必须要使用很多synchronized关键字来同步控制,所以必然会导致性能的降低

因此在使用的时候依照具体的情况而定。

 

同步与异步

同步和异步关注的是消息通信机制 (synchronouscommunication/ asynchronous communication)
所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回。但是一旦调用返回,就得到返回值了。
换句话说,就是由*调用者*主动等待这个*调用*的结果。

而异步则是相反,*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理这个调用。
典型的异步编程模型比如Node.js
举个通俗的例子:
你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。
而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

阻塞与非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
还是上面的例子,
你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了,当然你也要偶尔过几分钟check一下老板有没有返回结果。
在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。

 

JDK,SDK,JRE,JVM的区别

参考:http://blog.csdn.net/dreamcatchergo/article/details/8108467

SDK(Software DevelopKit,软件开发工具包)

用于帮助开发人员的提高工作效率。各种不同类型的软件开发,都可以有自己的SDK。Windows有WindowsSDK,DirectX 有 DirectX 9SDK,.NET开发也有Microsoft.NET FrameworkSDK。JAVA开发也不含糊,也有自己的Java SDK。

 JDK

Java SDK最早叫JavaSoftwareDevelop Kit,后来改名为JDK,即Java DevelopKit。JDK作为Java开发工具包,主要用于构建在Java平台上运行的应用程序、Applet 和组件等。

 JRE(Java RuntimeEnvironment,Java运行环境),

也就是Java平台。所有的Java程序都要在JRE下才能运行。

 JVM(Java VirtualMachine,Java虚拟机)

是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运

行。使用JVM就是为了支持与操作系统无关,实现跨平台。

 

布局总结

相对布局和帧布局:

相对布局是在统一个布局页面上面进行空间显示,如果你想将一个控件显示在另外一个控件上边是做不到的;另外一个控件会去挤对应的那个控件。因此,这里我们需要利用帧布局来解决这个问题;

帧布局和相对布局差不多,但是可以实现不同布局间的层叠;若要把一个控件放到另外一个控件左上角,我们可以将两个空间包裹在一个帧布局下eg:在控件A的右上角有一个功能键B,让控件A,matchParent,控件B aling_partent_right;就可以了;

 

控件gravity和作用范围:

我们知道Gravity是设置布局里面的子布局的位置,Layout_gravity设置的是本布局的效果;但是Gravity仅仅影响的是当前布局下的儿子,对其布局中的布局没用;

android:gravity="center"是对textView中文字居中

android:layout_gravity="center"是对textview控件在整个布局中居中(只在线性布局和帧布局中有用)

 

marging和padding

marging是外边距,padding是内部边距;如果不考虑背景的情况下两个差不多,但是考虑背景的情况,就有区别了!

 

通过inflator动态设置布局的注意点:

View mainView =LayoutInflater.from(context).inflate(R.layout.mygrouptab, null);

final LinearLayout.LayoutParams params =new    LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);

mainView.setLayoutParams(params);

this.addView(mainView);

 

 

<Button xmlns:android="http://schemas.android.com/apk/res/android"  

    android:layout_width="300dp"  

    android:layout_height="80dp"  

    android:text="Button" >  

</Button> 

平时我们经常使用layout_width和layout_height来设置View的大小,并且一直都能正常工作,就好像这两个属性确实是用于设置View的大小的。而实际上则不然,它们其实是用于设置View布局中的大小的;很明显Button这个控件目前不存在于任何布局当中,所以layout_width和layout_height这两个属性理所当然没有任何作用。最简单的方式就是在Button的外面再嵌套一层布局;

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  

    android:layout_width="match_parent"  

    android:layout_height="match_parent" >  

      <Button  

        android:layout_width="300dp"  

        android:layout_height="80dp"  

        android:text="Button" >  

    </Button>  

</RelativeLayout>

在setContentView()方法中,Android会自动在布局文件的最外层再嵌套一个FrameLayout,所以layout_width和layout_height属性才会有效果。这里,如果直接用setContentView()是将布局直接展示,我们同时可以将布局文件通过inflator转换成View对象,然后再对view对象进行操作;

相对布局中的layout_alignLeft,layout_toLeftOf的区别

在相对布局中alignLeft为相对与另外一个控件的内边沿

在相对布局中toLeftOf是相对于另外一个控件的外边缘

 

width和layout_width的区别

android:layout_width  只有两种选择一个是fill_parent ,二是wrap_content
android:width 这个是用来view的具体宽度的,以像素为单位。

 

相对布局的相对属性一览

android:layout_above          将该控件的底部置于给定ID的控件之上;

android:layout_below         将该控件的底部置于给定ID的控件之下;

android:layout_toLeftOf      将该控件的右边缘与给定ID的控件左边缘对齐;

android:layout_toRightOf     将该控件的左边缘与给定ID的控件右边缘对齐;

 

android:layout_alignBaseline 将该控件的baseline与给定ID的baseline对齐;

android:layout_alignTop     将该控件的顶部边缘与给定ID的顶部边缘对齐;

android:layout_alignBottom  将该控件的底部边缘与给定ID的底部边缘对齐;

android:layout_alignLeft    将该控件的左边缘与给定ID的左边缘对齐;

android:layout_alignRight    将该控件的右边缘与给定ID的右边缘对齐;

 

toLeftOf的用法

在相对不剧中,为了控制一些布局的终点,我们可以将用相对的布局toLeftOf来进行边界的控制;

 <TextView

    android:id="@+id/tv_content"

    style="@style/layout.xy"

    android:layout_alignParentLeft="true"

    android:layout_below="@+id/ll_date_title"

    android:layout_toLeftOf="@id/selzone_pic"

    android:layout_marginLeft="15dp"

    android:layout_marginRight="6dp"

    android:layout_marginTop="8dp"

    android:lineSpacingExtra="3dp"

    android:maxLines="2"

    android:ellipsize="end"

    android:textColor="@color/ubaby_txt_color_2"

android:textSize="13sp"           android:text="11111111111111111111111111111111111111111111111111111111111111"/>

这个里面让TextView靠左,为了不让它的内容越过selzone_pic控件,我们设定它的layout_toLeftOf;

 

为textView左边设置图片,和与图片的间距

android:drawablePadding="10dp"

android:drawableLeft="@drawable/home_manage_button"

 

shape创建半透明膜层

透明度:00为透明,FF为不透名;

<gradient

   android:startColor="#55000000"

   android:endColor="#11eeeeee"

   android:angle="90"

   />

 

动态为View加入一些特殊属性:

RelativeLayout.LayoutParams params=newRelativeLayout.LayoutParams(

LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);

params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

params.addRule(RelativeLayout.CENTER_VERTICAL);

itemLayout.addView(deleteButton,params);

 

生命周期

Activity生命周期

Activity的launchmode为默认值

1、桌面图标启动Ap,按Back键返回:

onCreate()
onStart()
onResume()
Back键按下】
onPause()
onStop()
onDestroy()

2.长按Home按键,从最近程序中点击图标进入:

与情况1相同。

3.启动Ap,按Home按键,然后再点击图标进入:

onCreate()
onStart()
onResume()
Home键按下】
onPause()
onStop()
【再次进入Ap
onRestart()
onStart()
onResume()

4.新Activity全部覆盖,back退出新Activity:

A1 oncreate()
A1 onstart()
A1 onResume()
【启动A2
A1 onPause()
A2 onCreate()
A2 onStart()
A2 onResume()
A1 onStop()
【从A2 Back
A2 onPause()
A1 onActivityResult()
A1 onRestart()
A1 onStart()
A1 onResume()
A2 onStop()
A2 onDestroy()
【从A1 Back
A1 onPause()
A1 onStop()
A1 onDestroy()

5.新Activity部分覆盖,back退出新Activity

A1 onCreate()
A1 onStart()
A1 onResume()
【启动A2
A1 onPause()
A2 onCreate()
A2 onStart()
A2 onResume()
【从A2Back
A2 onPause()
A1 onActivityResult()
A1 onResume()
A2 onStop()
A2 onDestroy()

6.普通Dialog部分覆盖:

同AlertDialog

7.AlertDialog部分覆盖:

onCreate()
onStart()
onResume()
【显示AlertDialog】
【关闭AlertDilaog】
在AlertDialog出现以及消失的过程中,没有触发任何onXXX事件

8.来电覆盖:

等同新Activity全覆盖

9.桌面控件intent启动:

9.1.目标Activity未启动:

等同桌面图标直接启动,会直接启动一个新Activity。

9.2.目标Activity已经启动并且在最上层

如果目标Activity是由桌面控件触发的,那么等同情况3,不会创建新Activity。
如果目标Activity是由Launcher图标启动的,那么会不停的创建新Activity。

9.3.目标Activity已经启动但是不在最上层

如果目标Activity是由桌面控件启动的,那么不会创建新Activity,但也不会把目标Activity提到最上层。
如果目标Activity是由Launcher图标启动的,那么会不停的创建新Activity。

 



Oncreate和onNewIntent启动顺序:

 

---------------------------------------------------------------------------

<activityandroid:label="@string/app_name"

android:launchmode="singleTask"

android:name="Activity1">

</activity>

launchModesingleTask的时候,通过Intent启到一个Activity,如果系统已经存在一个实例,系统就会将请求发送到这个实例上,但这个时候,系统就不会再调用通常情况下我们处理请求数据的 onCreate方法,而是调用onNewIntent方法,如下所示:

 

不要忘记,系统可能会随时杀掉后台运行的Activity,如果这一切发生,那么系统就会调用onCreate方法,而不调用onNewIntent方法,一个好的解决方法就是在onCreate和onNewIntent方法中调用同一个处理数据的方法

 

OnCreate和onFinishInflate()顺序

看过Activity的生命周期就知道了(SDK上有详细介绍),onCreate肯定是第一个调用的函数; 
应用程序的入口是Activity,而Activity第一个调用的是函数onCreate ;
创建Activity后,应用程序会从xml读入相应的view,所有的view都读进来以后会调用onFinishInflate()

 

View的布局渲染生命周期


ondestroy()和 startActivityForResult()调用顺序:


上图仅仅是从A跳转到B时候,再从B恢复到A的时候监测到的A的logcat打印;

实际上ondestroy遵循的原则是:当我们在ondestroy中调用有些耗时操作时,它首先执行的是尽快回复上一个UI,然后再去执行和停止当前UI;

 

Activity.finish()
Call this when your activity is done and should be closed.
在你的activity动作完成的时候,或者Activity需要关闭的时候,调用此方法。
当你调用此方法的时候,系统只是将最上面的Activity移出了栈并没有及时的调用onDestory()方法,其占用的资源也没有被及时释放。因为移出了栈,所以当你点击手机上面的“back”按键的时候,也不会再找到这个Activity。
Activity.onDestory()
the system is temporarily destroying this instance of the activity to save space.
系统销毁了这个Activity的实例在内存中占据的空间。
在Activity的生命周期中,onDestory()方法是他生命的最后一步,资源空间等就被回收了。当重新进入此Activity的时候,必须重新创建,执行onCreate()方法。
System.exit(0)
这玩意是退出整个应用程序的,是针对整个Application的。将整个进程直接KO掉。


------------------------------------------

finish函数仅仅把当前Activity退出了,但是并没有释放他的资源。安卓系统自己决定何时从内存中释放应用程序。当系统没有可用内存到时候,会按照优先级,释放部分应用。

2、Service生命周期

service有两种启动方式,startService()和bindService();

 

安卓小知识点

日期类:

对于日期来说我们有几个量,一个是常用的年月日时分秒,另外一个是一个时间戳(他是从1970年1月1日起的微秒数)的东西。

日期类的使用:

第一步:得到一个Date类

Date(事件戳);

Date(年,月,日);

这两种构造参数比较常用的;

第二步:

通过Date对象,我们对Calender类进行初始化,然后就差不多能得到有关事件的相关数据了。

 

具体的日获取可以直接通过Calebnder的方法获取:

int sYears = sCalendar.get(Calendar.YEAR);          

int sMonths = sCalendar.get(Calendar.MONTH);  

int sDays = sCalendar.get(Calendar.DAY_OF_YEAR);  

输出格式变化可以用:

SimpleDateFormat formatter = newSimpleDateFormat("YYYY MM DD HH:mm");

String time = formatter.format(Date对象);

 

例子:通过已知年月日获取星期

Calendarcalender = Calendar.getInstance();

calender.set(calender.YEAR, year); 

calender.set(calender.MONTH, month-1);  // 1月为0

calender.set(calender.DATE, day); 

int  week= calender.get(calender.DAY_OF_WEEK);  //周日为1

 

// 将时间戳转化为对应日期;

long babyBirthTimeStamp =Long.parseLong(babyBirth);

Date creDate = new Date(babyBirthTimeStamp);

SimpleDateFormatformatter = new SimpleDateFormat("yyyyMMdd");

babyBirth = formatter.format(creDate);

String输出格式转换:

int型数据补零:

String.format("%06d",12);//其中0表示补零而不是补空格,6表示至少6位

 

带参数的String的格式输出

<stringname="over_base_mile_price" formatted="false">超过%s公里后,超出部分每公里为%s元</string>

 

String.format(CommonUtils.getString(R.string.over_base_mile_price),carInfo.base_mile, carInfo.mile_price)

 

invalidate和postInalidate和requestLayout的区别:

invalidate():实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,必须是在UI线程中进行工作。比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。原理:invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。

一个Android 程序默认情况下也只有一个进程,但一个进程下却可以有许多个线程。

在这么多线程当中,把主要是负责控制UI界面的显示、更新和控件交互的线程称为UI线程,由于onCreate()方法是由UI线程执行的,所以也可以把UI线程理解为主线程。其余的线程可以理解为工作者线程。

invalidate()得在UI线程中被调动,在工作者线程中可以通过Handler来通知UI线程进行界面更新。
postInvalidate():在工作者线程中被调用;

requestLayout():invalidate主要是执行的是ondraw阶段,不再对ViewGroup进行onMeasure和onLayout;

requestLayout会重新去执行onMeasureonLayout

canvas的save和restore:

save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。

restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。

setContentView()和LayoutInflater的区别:

setContentView是将传入的View或者资源布局直接显示到屏幕上;

而LayoutInflater()是将资源布局转化为实例对象View;之后要显示还得靠 setContentView;

Dialog的cancle和dismiss的区别:

Cancel the dialog. Thisis essentially the same ascallingdismiss(), but it will also call your DialogInterface.OnCancelListener (if registered).

取消对话框,基本上和调用dismiss效果一样。但是cancel同事也会调用DialogInterface.OnCancelListener注册的事件,如果注册了。

Dismiss this dialog, removing itfrom the screen. This method can be invokedsafely from any thread. Note that you should notoverride this method to do cleanup when the dialog is dismissed, insteadimplement that inonStop().

 

View中setTag和getTag用法:

View中的setTag(Onbect)表示给View添加一个额外的数据,以后可以用getTag()将这个数据取出来。
可以用在多个Button添加一个监听器,每个Button都设置不同的setTag。这个监听器就通过getTag来分辨是哪个Button 被按下。

import android.app.Activity;    
import android.os.Bundle;    
import android.view.View;    
import android.widget.Button;    
   
public class Main extends Activity {    
    @Override   
    public void onCreate(Bundle savedInstanceState){    
        super.onCreate(savedInstanceState);    
       setContentView(R.layout.main);    
        Button button1 = (Button)findViewById(R.id.Button01);    
        Button button2 = (Button)findViewById(R.id.Button02);    
        Button button3 = (Button)findViewById(R.id.Button03);    
        Button button4 = (Button)findViewById(R.id.Button04);    
        MyListener listener = newMyListener();    
       button1.setTag(1);    
       button1.setOnClickListener(listener);    
       button2.setTag(2);    
        button2.setOnClickListener(listener);    
       button3.setTag(3);    
       button3.setOnClickListener(listener);    
       button4.setTag(4);    
       button4.setOnClickListener(listener);    
    }    
   
    public class MyListener implements View.OnClickListener{    
   
        @Override   
        public void onClick(View v){    
            int tag =(Integer) v.getTag();    
            switch (tag){    
            case1:    
               System.out.println("button1 click");    
               break;    
            case2:    
               System.out.println("button2 click");    
               break;    
            case3:    
               System.out.println("button3 click");    
               break;    
            case4:    
               System.out.println("button4 click");    
               break;    
           }    
        }    
    }    

 

将对象通过intent序列化传输

这里传输的是2进制的序列化对象,在接受的时候需要进行转化

传输:

intent.setClass(ApplicationManager.getContext(),DisplayImageActivity.class);

intent.putExtra(ForumParams.IMAGE_URL_ARRAY,diaryBean.pictures);

接收:

final Intent intent = getIntent();

Serializable obj =intent.getSerializableExtra(ForumParams.IMAGE_URL_ARRAY);

备注:

除了继承serliazable这种方式之外,也可以通过

1、实现parcelble接口来完成intent的对象的传输;

2、将对象转化成json的string串进行传输。

 

setClickable和setEnable的区别:

setClickable:这个函数的意思是让按键按一下。比如弄一个定时器,然后在手机上模拟,多长时间到了让按键自己按一下,而不是手动去按,可以用这个函数。

setEnable:这个函数才是真正的,让一个按键可以被用户按,或者不可按。如果设为false,按键则会变成灰色的,按上去也没反应。当设为true后,才会正常使用。

inflate的使用:

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) 

inflate有三个参数填充的父布局填充的父布局是否将填充的布局放入父布局中

 

LinearLayoutlayout = (LinearLayout)findViewById(R.id.container);

View view = inflater.inflate(R.layout.linearlayout, layout, true); 

layout.addView(view);

 

你就会发现这样写会崩溃!然后下面这样写就没问题了:

LinearLayoutlayout = (LinearLayout)findViewById(R.id.container);

inflater.inflate(R.layout.linearlayout, layout, true); 

原因

inflater.inflate方法自动将生成的View添加到了这个ViewGroup root中去了!!同时View布局的LatyoutParams参数将用父布局的参数;

我们同时可以用final ViewGroup item = (ViewGroup)View.inflate(R.layout.vaccine_item_content, null);

将布局转化为View对象;

注意

如果在用inflate时父布局为null,则

view的父布局是一个FrameLayout,而这个FrameLayout就是由系统自动帮我们添加上的。

说到这里,虽然setContentView()方法大家都会用,但实际上Android界面显示的原理要比我们所看到的东西复杂得多。任何一个 Activity中显示的界面其实主要都由两部分组成,标题栏和内容布局。标题栏就是在很多界面顶部显示的那部分内容,比如刚刚我们的那个例子当中就有标题栏,可以在代码中控制让它是否显示。而内容布局就是一个FrameLayout,这个布局的id叫作content,我们调用setContentView()方法时所传入的布局其实就是放到这个FrameLayout中的,这也是为什么这个方法名叫作setContentView(),而不是叫setView()。

最后再附上一张Activity窗口的组成图吧,以便于大家更加直观地理解:

 

pendingIntent的使用:

pendingIntent字面意义:等待的,未决定的Intent。
要得到一个pendingIntent对象,使用方法类的静态方法

getActivity(Context,int,Intent,int)

getBroadcast(Context,int,Intent,int)

getService(Context,int,Intent,int

分别对应着Intent3个行为,跳转到一个activity组件、打开一个广播组件和打开一个服务组件。

参数有4个,比较重要的事第一个和第三个,其次是第四个和第二个。可以看到,要得到这个对象,必须传入一个Intent作为参数,必须有context作为参数。

pendingIntent是一种特殊的Intent。主要的区别在于Intent的执行立刻的,而pendingIntent的执行不是立刻的。pendingIntent执行的操作实质上是参数传进来的Intent的操作,但是使用pendingIntent的目的在于它所包含的Intent的操作的执行是需要满足某些条件的。
主要的使用的地方和例子:1、通知Notification的发送2、短消息SmsManager的发送3、警报器AlarmManager的执行等等。

PendingIntent可以看作是对Intent的包装。PendingIntent主要持有的信息是它所包装的Intent和当前ApplicationContext。正由于PendingIntent中保存有当前Application的Context,使它赋予带他程序一种执行的Intent的能力,就算在执行时当前Application已经不存在了,也能通过存在PendingIntent里的Context照样执行Intent。

根据字面意思就知道是延迟的intent,主要用来在某个事件完成后执行特定的Action。PendingIntent包含了Intent及Context,所以就算Intent所属程序结束,PendingIntent依然有效,可以在其他程序中使用。
常用在通知栏及短信发送系统中。

PendingIntent一般作为参数传给某个实例,在该实例完成某个操作后自动执行PendingIntent上的Action,也可以通过PendingIntent的send函数手动执行,并可以在send函数中设置OnFinished表示send成功后执行的动作。

将String数据转化为Json数据:

JSONObject json =new JSONObject(day.calinfo.babySleepValue);

Iterator<String> keys =json.keys();

String key = keys.next();

String detail = json.getString(key);

if (!TextUtils.isEmpty(detail)) {

   JSONObject valueJson = new JSONObject(detail);

timeKey = Misc.parseLong(key, 0);

startTime =Misc.parseLong(valueJson.getString("volume"), 0);

endTime =Misc.parseLong(valueJson.getString("feedway"), 0);

}

如果用第三方gson库的话转换起来就不用那么麻烦了。

Bitmap - 称作位图,一般位图的文件格式后缀为bmp,当然编码器也有很多如RGB565、RGB888。作为一种逐像素的显示对象执行效率高,但是缺点也很明显存储效率低。我们理解为一种存储对象比较好。

Drawable - 作为Android平下通用的图形对象,它可以装载常用格式的图像,比如GIF、PNG、JPG,当然也支持BMP,当然还提供一些高级的可视化对象,比如渐变、图形等。

Canvas - 名为画布,我们可以看作是一种处理过程,使用各种方法来管理Bitmap、GL或者Path路径,同时它可以配合Matrix矩阵类给图像做旋转、缩放等操作,同时Canvas类还提供了裁剪、选取等操作。

Paint - 我们可以把它看做一个画图工具,比如画笔、画刷。他管理了每个画图工具的字体、颜色、样式。

ImageView 中 XML 属性 src 和 background 的区别:

background 会根据 ImageView组件给定的长宽进行拉伸, 而 src 就存放的是原图的大小, 不会进行拉伸。src 是图片内容(前景), bg 是背景, 可以同时使用。

此外: scaleType 只对 src 起作用;bg 可设置透明度, 比如在 ImageView 中就可以用 android:scaleType 控制图片的缩放方式, 示例代码如下:

<ImageView android:id="@+id/img"

        android:src="@drawable/logo"

        android:scaleType="centerInside"

        android:layout_width="60dip"

        android:layout_height="60dip"

        android:layout_centerVertical="true"/>

说明: centerInside 表示按比例缩放图片, 使得图片长 (宽)的小于等于视图的相应维度。

注意: 控制的图片为资源而不是背景.

layout 中设置应该: android:src=”@drawable/logo”

而不是 android:background=”@drawable/logo”

代码设置应该是: imgView.setImageResource(R.drawable.*);

而不是 imgView.setBackgroundResource(R.drawable.*);

安卓中的引用:

在安卓当中,它的引用的用法类似于c++当中的指针,只是由于自动回收机制的存在,让我们在使用引用的时候有了区别,即根据回收的强度,分为引用

它的定义为:

private final WeakReference<BitmapLoaderTask>bitmapLoaderTaskReference;

bitmapLoaderTaskReference = new WeakReference<BitmapLoaderTask>(bitmapLoaderTask);

安卓退出当前应用:

if (exitApp) {

  getContext().unregisterReceiver(webviewForward);

  finish();

System.exit(0);

一般直接用System.exit(0);这里需要将之前的栈都清空,防止在关闭时因为资源太多,导致配置低的手机出现短暂黑屏现象;

打印当前的任务栈:

ActivityManageractivityManager =(ActivityManager) ApplicationManager.getContext().getSystemService(Context.ACTIVITY_SERVICE);

List<ActivityManager.RunningTaskInfo>tasks = activityManager.getRunningTasks(20);

for (ActivityManager.RunningTaskInfotask : tasks) {

  Log.d("hhh", task.baseActivity.getPackageName());

}

对于全局的异常,我们可以通过

UncaughtExceptionHandler类捕获崩溃异常;在里面可以将捕获到的异常处理成json上传服务器,在服务器中进行备份;

 

软件盘显示:

对于软键盘显示,我们在清单文件中可以进行配置:

stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置

stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示

stateHidden:用户选择activity时,软键盘总是被隐藏

stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的

stateVisible:软键盘通常是可见的

stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态

adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示

adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间

adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分

异步更新UI的方法

Activity.runOnUiThread(Runnable)

View.post(Runnable)

View.postDelayed(Runnable,long)

例如,您可以通过使用 View.post(Runnable) 

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            final Bitmap bitmap =loadImageFromNetwork("http://example.com/image.png");
            mImageView.post(new Runnable() {
                public void run() {
                   mImageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值