以前做Android开发的时候没怎么做笔记,也没写博客,有什么需要记的东西都是这个word放一点,那个txt放一点,现在都不知道到哪里找了,不过总归还是找到一两个word,整理了一下,便有了这篇文章,其中有自己的一些领悟,也有从互联网上摘抄的东西。
(一)关于Activity的启动问题:
1、Activity从创建到进入运行态所触发的事件onCreate()-->onStart()-->onResume()
2、从运行态到停止态所触发的事件 onPause()--->onStop()
3、从停止态到运行态所触发事件 onRestart()-->onStart()--->onResume()
4、从运行态到暂停态所触发事件 onPause()
5、从暂停态到运行态所触发事件 onResume()
(二)关于Service启动问题
使用intent.startService() 启动Service: Service与Activity没有关系,也没有通信,就算Activity退出了,Service可能还在。
intent.startService() ->onCreate()- >onStartCommand()->Service running intent.stopService() | ->onDestroy() ->Service stop使用intent.bindService()启动Service:Service与Activity有通信
intent.bindService()->onCreate()->onBind()->Service running onUnbind() -> onDestroy() ->Service stop
Notification就是手机上方经常出现的通知,由于Notification可以与应用程序脱离。也就是说,即使应用程序被关闭,Notification仍然可以显示在状态栏中。就像短信应用没有启动,但是手机上方会出现通知。当应用程序再次启动后,又可以重新控制这些Notification。如清除或替换它们。因此,需要创建一个PendingIntent对象。该对象由Android系统负责维护,因此,在应用程序关闭后,该对象仍然不会被释放。这里说一下PendingIntent和Intent的区别:An Intent is something that is used right now; a PendingIntent is something that may create an Intent in the future. You will use a PendingIntent with Notifications, AlarmManager, etc.
(四)关于程序数据类型
Sqlite只支持null,integer,real,text和blob(二进制对象)数据类型,也兼容其他的varchar等等,但实际上在运算的时候会自动转换为五种类型,特点:保存任何类型的数据到任何字段中
(五)关于webwiew
在WebView的设计中,不是什么事都要WebView类干的,有些杂事是分给其他人的,这样WebView专心干好自己的解析、渲染工作就行了。WebViewClient就是帮助WebView处理各种通知、请求事件的,具体来说包括:
onLoadResource onPageStart onPageFinish onReceiveError onReceivedHttpAuthRequest
WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等
onCloseWindow(关闭WebView) onCreateWindow() onJsAlert (WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出) onJsPrompt onJsConfirm onProgressChanged onReceivedIcon onReceivedTitle
webView.loadUrl("file:///android_asset/index.html"); -----打开本包内asset目录下的index.html文件 webView.loadUrl("content://com.android.hello/sdcard/index.html");-----打开本地sd卡内的index.html文件
android能操作文件夹只有两个地方:
1.sdcard
2./data/<package_name>/
详见apidoc:
docs/guide/topics/data/data-storage.html#filesExternal
Environment.getRootDirectory()是得到系统/System目录
Environment.getExternalStorageState()是得到系统/Sdcard目录,需要判断是否有Sdcard
Environment.getDataDirectory()是得到/Data目录;
WebView加载网页时前面的那一段空白怎么填补?Toast不能定义时间,所以不行,会在加载没有完成的时候就灭了。可以在背景用一个View试试。每次加载开始时就让WebView消失而View显示。
关于网页加载进度提示的问题:
Toast提示网页加载进度可以在WebViewClient.onPageStart方法里面设置开始show,在WebChromeClient.onProgressChanged方法里面progress==100的时候结束cancel,其中设置WebChromeClient有如下方法webView.setWebChromeClient(WebChromeClient).
(六)关于程序意外退出后的保存问题
当你的程序中某一个ActivityA在运行时中,主动或被动地运行另一个新的ActivityB ,这个时候A会执行:
public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putLong("id", 1234567890); }
B完成以后又会来找A,这个时候就有两种情况,一种是A被回收,一种是没有被回收,被回收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上参数savedInstanceState,没被收回的就还是onResume就好了。savedInstanceState是一个Bundle对象,你基本上可以把他理解为系统帮你维护的一个Map对象。在onCreate()里你可能会用到它,如果正常启动onCreate就不会有它,所以用的时候要判断一下是否为空。
if(savedInstanceState != null){ long id = savedInstanceState.getLong("id"); } if(savedInstanceState != null){ long id = savedInstanceState.getLong("id");}
就像官方的Notepad教程里的情况,你正在编辑某一个note,突然被中断,那么就把这个note的id记住,再起来的时候就可以根据这个id去把那个note取出来,程序就完整一些。这也是看你的应用需不需要保存什么,比如你的界面就是读取一个列表,那就不需要特殊记住什么,哦,没准你需要记住滚动条的位置...
(七)关于摄像头
摄像头的实现有Camera,SurfaceView,SurfaceHolder,SurfaceHolder.Callback,PictureCallback,Camera.Parameters,Display
首先SurfaceView相当于那个画面,也就是取景框。而设置SurfaceView需要一个SurfaceHolder,Camera通过setPreviewDisplay(SurfaceHolder)的方法来连接SurfaceHolder并通过它来控制SurfaceView,SurfaceHolder.Callback是SurfaceHolder用来显示SurfaceView数据的接口,它实现了三个方法:
surfaceCreated()当SurfaceView被创建时调用。
surfaceChanged()当SurfaceView发生改变时调用.
surfaceDestroyed()当surfaceView销毁时进行调用.
SurfaceHolder通过addCallBack()方法将相应的接口绑定到它身上.
PictureCallback是Camera调用拍照方法takePicture(,,PictureCallback)的接口类,拍照的数据就在这个类里面的OnPictureTake()方法里面实现,对照片数据进行解析和存储。
Camera.Parameters是对Camera的一些拍照参数进行设置,如照片大小,照片格式等等。
Display是得到系统屏幕的一些参数.用来设置Camera的参数跟系统屏幕符合,如照片大小是否跟系统屏幕一样大.
默认情况下照相机的取景方向是向左旋转90°的。只设置orientation屏幕能转过来,但是拍出来的照片还是向左旋转90°的。
parameters.set("orientation","portrait");//"portrait"是竖向,仅仅是试图的方向
parameters.setRotation(90);//应该是旋转找出来的照片方向
相机旋转依赖于不同的设备和不同的版本,下面是一个国外论坛比较经典的总结(http://code.google.com/p/android/issues/detail?id=1193#c42):
Version1.6:tofixtheRotationIssue,anditisgoodformostofdevices
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { p.set("orientation", "portrait"); p.set("rotation",90); } if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { p.set("orientation", "landscape"); p.set("rotation", 90); }
Version2.1:dependonkindofdevices,forexample,CanntfixtheissuewithXPeriaX10,butitisgoodforX8,andMini
Camera.Parameters parameters = camera.getParameters(); parameters.set("orientation", "portrait"); camera.setParameters(parameters);
Version2.2:notforalldevices
camera.setDisplayOrientation(90);
在做照相机程序的时候,一直不知道怎么在SurfaceView里面添加按钮,SurfaceView一般是全屏显示的,下面的FrameLayout是重点
<?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" > <FrameLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" > <SurfaceView android:id="@+id/surfaceView" android:layout_width="fill_parent" android:layout_height="fill_parent" > </SurfaceView> </FrameLayout> <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="返 回"></Button> </LinearLayout> </LinearLayout>
布局的问题:如果是两个空间来平分宽度,就用LinearLayout,然后两个控件都设置layout_weight=1,这样就可以很好的平分宽度了;如果三个平分的话就在中间那个控件单独弄一个LinearLayout或者其他的layout,这个layout的android:layout_weight="1"
,这样的话这个layout就有2/3的宽度,然后反正这个layout里面的控件设置属性android:layout_centerInParent="true"就能够在中间了
关于图像裁剪:
调用系统裁剪图片的主要代码是下面这些代码,这里不能设置得到哪些图片,应该是得到所有的图片,裁剪后可以自己设置路径和文件名
Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(photoUri, "image/*"); intent.putExtra("crop", "true"); //crop=true有这句才能出来最后的裁剪页面.intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1); intent.putExtra("outputX", 80); intent.putExtra("outputY", 80); intent.putExtra("return-data", true); intent.putExtra("output", Uri.fromFile(tempFile)); intent.putExtra("outputFormat", "JPEG"); startActivityForResult(intent, requestCode);
(八)关于GPS
只有启用了这个函数LocationManager.requestLocationUpdates(……);GPs才会起作用,这是一个请求更新函数,里面有一个监听器的参数,能够监听到位置的改变。
android的位置提供有两个,gps和network,其中network包括wifi和基站等网络方式,gps每次获取的位置一般都是不同的,network获取的经纬度在一般很少改变,如果从wifi切换到移动网络,则获取的经纬度会发生变化,反之从移动网络切换到wifi,获取的经纬度也会发生变化,但是如果一直在移动网络,或者一直在wifi网络,则获取的经纬度在几次之内是很少会改变的。当然如果从一个wifi热点切换到另一个wifi热点,获取的经纬度肯定会变化。不变化的是在一个wifi热点内的周围移动获取的经纬度是基本不变的。在不同网络切换到时候获取的经纬度可能在一段时间内会变化,但最终会趋于稳定。例如:
我一开始用wifi获取的是23.0984789--113.3162901(wifi),之后关闭wifi,获取的是23.0981123--113.3154123(基站),(中间还有一两个其他的值,也可以没有)最后趋于23.0981189--113.3154709(基站),开启wifi后,得到23.0984123--113.3162123(wifi),(中间还有几个值,也可以没有),最后趋于23.0984789--113.3162901(wifi),注意到最后趋于稳定的值都是一样的。
(九)关于游戏开发
1:被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于onTouch来更新,可以直接使用invalidate。因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。
2:surfaceview中确实有onDraw这个方法,但是你surfaceview不会自己去调用!!!放在线程中不断调用的,一定要注意!!在继承view中,因为onDraw方法是系统自动调用的,不像在surfaceview这里这样去在run里面自己去不断调用,在view中我们可以抵用invalidate()/postInvalidate()这两种方法实现让系统调用onDraw方法,这里也是和surfaceview中的不同之一!
3:这里canvas.save();和canvas.restore();是两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的。这里稍微解释一下,当我们对画布进行旋转,缩放,平移等操作的时候其实我们是想对特定的元素进行操作,比如图片,一个矩形等,但是当你用canvas的方法来进行这些操作的时候,其实是对整个画布进行了操作,那么之后在画布上的元素都会受到影响,所以我们在操作之前调用canvas.save()来保存画布当前的状态,当操作之后取出之前保存过的状态,这样就不会对其他的元素进行影响
(十)其他知识点
1)Android基于http上传文件到服务器端要分析文件的流格式,自己来组装流格式来发送到服务器端。在服务器端通过开源的一个组件commonsfileupload来实现文件流的解析。
2)真机和模拟器访问本机都是用10.0.2.2,因为127.0.0.1是模拟器本身的地址。但是如果是真机测试,则服务器的地址就是本机自己的ip地址
3) 要想监听电话的来电状态,信号强度等,可以通过 TelephonyManager 来实现,具体是得到一个电话管理器对象 TelephonyManager ,然后通过listen()方法设置相应的器PhoneStateListener来监听电话的各种状态.PhoneStateListener是里面有相应的回调函数,如OnSignaStrengthsChanged()方法是当电话的强度改变时就会调用。