android分享

我在编写android程序时,遇到的瓶颈不是某个小功能怎么去做,而是被系统内部工作原理卡住了。所以,我要给大家介绍android应用程序的特点:没有鼠标按下之类的事件(只有触摸事件),右键菜单(常按条目),主菜单(手机上的菜单按钮),关闭对话框和菜单(用手机上的返回按钮),一个正在运行的程序被调到后台了,是保持它活动,还是终止它呢?这对写程序很有影响。例如在词库中输入ramificat,接着又调出其他程序,还能回到词库中看到ramificat和接着输入吗?用回退键隐藏词库,用主菜单键隐藏词库的效果就不同。用户离开一个任务后,还可能回来吗?这个不好说,系统可以杀这个任务,也可以不杀,最终由系统在需要内存的时候杀掉这个任务。对于回退键,则表示用户不想要这个任务了,系统会杀掉这个任务。


1.eclipse使用-->adt插件-->android sdk-->依赖platforms,(不需要jdk,这点千万别闹笑话!对找工作吹牛皮时特有用)
为eclipse安装adt插件时,eclipse要上网去找更新版本的adt,而学生电脑上不了网,所以速度会很慢,这时候把网线拔掉,安装速度就提上来了。


2.先告诉大家如何用android命令创建AVD,再用emulator -avd xxx命令启动仿真器,最后演示如何用adb命令安装apk和执行shell命令。
  先得让大家了解下android手机,用模拟器演示如何发送短信,如何拨打和接听电话,如果查看文件目录,如何安装程序。
1)android
2)android list avds
3)emulator -avd xxx
4)adb devices
5)adb -s emulator-5554 install xxx.apk  (用桌面上带空格和中文的apk也没问题)
6)adb -s emulator-5554 shell
       ls
       ps
       kill pid




3.第一个android程序
(创建新工程时,adt插件必须要找到android sdk,因为它只是一个壳,必须指定它调用的实际开发工具android sdk)
(在运行时一定要分析为什么要创建AVD?有的老师讲课忘记了这个,说明讲课思路没缕顺和备课不充分) 


现在计算机程序的界面可以理解成窗口的层层嵌套,即大窗口里套小窗口,程序无论如何都得有一个大窗口,大窗口里的小窗口则是可有可无。
一个Activity就是一个可以与用户交互的主框架窗口,相当于大家平常见到的Windows窗口程序的边框,这个框架窗口可以填充进视图子窗口。Activity中不设置setContentView(),照样可以接受触摸和键盘事件。


Activity的OnTouchEvent()方法内处理MotionEvent.ACTION_DOWN时,不管返回true,还是false,都会发生MotionEvent.ACTION_UP,而自定义View的OnTouchEvent()方法内处理MotionEvent.ACTION_DOWN时返回false会屏蔽MotionEvent.ACTION_UP事件,这可以通过设置setClickable方法来解决。当View的OnTouchEvent()方法返回true,会阻止该事件传播给Activity的OnTouchEvent()方法。


OnKeyDown()方法中if(keyCode == KeyEvent.KEYCODE_BACK){不管是返回true,还是false},都不会再调用super.onKeyDown(),这样就不会终止当前Activity了,可以看Activity.onKeyDown方法的帮助说明,和看super.onKeyDown()的源码。最好的方式是处理onBackPressed(),如果要结束程序,就调用父类的super.onBackPressed(),否则,不调用super.onBackPressed()即可。


通常方式创建的对话框有点“类似”windows程序中的非模态对话框,对话框不用关闭,dialog.show()方法后面的代码也会立即执行。既然如此,我们就无法在onBackPressed方法中采用类似if(条件){onsuper.onBackPressed()}的方式来结束程序了,只能是在对话框的按钮单击事件中直接关闭程序了。这可能是因为Android的事件处理方法的响应时间不能大于5s,而对话框弹出后等待用户操作的时间经常会超过5s。另外,弹出对话框不会导致Activity的onpause方法方法调用,虽然这时候Activity表面上看起来被遮挡住了一部分且变灰了。
应该用showDialog方法显示对话框,显示的对话框则由onCreateDialog方法返回得到。


layout.xml文件名种不能出现大写字母。


屏幕上有多个view时,onkeydown只能被具有焦点的view感受到。
在具有焦点的View类的Onkeydown方法中返回true,也可以屏蔽掉Activity类中的Onkeydown事件,包括终止应用程序的back键。两个View之间可以用如下配置切换焦点,其中第一个视图引用第二个视图的id时,使用到了"+"号,否则eclipse报错,配置细节是查看View类的API帮助文档获知和猜测出来的:


<cn.itcast.android.MyView
    android:layout_width="fill_parent" 
    android:layout_height="100dip" 
    android:focusable="true" 
    android:background="@android:color/background_light"
     android:id="@+id/nextview1"   
    android:nextFocusDown="@+id/nextview2"
/>
<cn.itcast.android.MyView
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:focusable="true" 
    android:id="@+id/nextview2"
     android:nextFocusDown="@id/nextview1"   
     android:background="@android:color/darker_gray"     
/> 
测试代码如下(注意:如果onkeydown方法中返回了true,那么,也无法实现按down键时切换焦点的效果了,所以,测试焦点时要用返回false):
protected void onFocusChanged(boolean gainFocus, int direction,
Rect previouslyFocusedRect) {
System.out.println(this + ":focus:" + gainFocus);
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
System.out.println(this + ":MyView keydown:" + keyCode);
return false;
}








我们的一个项目中可以有多个这样的Android部件,好比一个java项目中有多个启动类,只是这个Activity部件是由Android系统通过某种方式去激活。


程序清单文件中的“意图过滤”让程序出现在启动程序列表中和长按主菜单键显示最近使用的程序时罗列出来。






演示A程序的Activity调用B程序中的Activity,B中的清单文件的配置:
 <permission android:name="cn.itcast.it315" android:protectionLevel="normal"></permission>  
...
        <activity android:name=".MainActivity" android:screenOrientation="portrait"
                  android:label="@string/app_name" android:permission="cn.itcast.it315">
....
            <intent-filter>
            <action android:name="cn.itcast.action.mycompass"/>
  <category android:name="android.intent.category.DEFAULT" />            
            </intent-filter>
        </activity>


"android.intent.category.DEFAULT"这个字符串定义成了Intent.CATEGORY_DEFAULT常量。


说startActivity()自动在Intent增加上面这个category,搜索源码没找到,能提供更具体的源码吗?
关于意图,ppt中还有好多地方说得很糊涂。我个人的总结就是:意图过滤器中的内容要包含意图中的内容,意图中也要至少出现一个意图过滤器设置的action和dataAndType,意图中可以不出现category。


看“Security and Permissions”文章中的“Using Permissions”部分,可以看到如下一句话:
The permissions provided by the Android system can be found at Manifest.permission
接受开机广播的intent-filter的action值和许可,分别可以在Intent类和Manifest.permission中通过搜索boot关键字来找到对应的常量。


D:\android_bundle\android-sdk-windows\platforms\android-8\sources\base\core\res\AndroidManifest.xml,这个文件中定义了系统预定义的许可。




4.程序结构
  @看成是R文件,.代表当前应用的所在包,如果有子包,则不能省略。
mustang(野马)
  项目清单文件是软件安装时由操作系统读取用的,android的五大组件只能放在应用包或应用包的子包下面。在布局文件中把TextView复制几个,看看显示效果,再解释布局layout_width和layout_height属性:它们的值只能是fill_parent和wrap_content吗?不能自己设置一个整数?


n.关于adb


关于软件打包签名成apk文件,说是保护作者,我不这么认为!


遇到一个eclipse+adt总是处于停滞状态的情况,把用户主目录下的.android删除掉就解决了。
在布局文件中设置android:id属性为"@+xx/yy"
提供的android sdk怎么自动关联上源代码的?
在方法上按下f2可以看到其方法签名(这要关联上源码吗?)
发短信输入很多内容后按钮就看不见了,按什么键把按钮调出来的?
帧布局中要显示两个元素,把上面的元素做成透明的,怎么做成透明呢?
相对布局文档中的background背景图片设置成了@drawable/blue。
fill_parent不是不是与父元素一样的宽度,而是说占用父元素中剩余的空间。
androidtest工程的配置文件编写不用搞那么复杂,直接用adt工具创建即可。
手机自己的内存就像pc自己的内存,sdcard为外存,就像pc机的硬盘
将短信发送器程序改成relativelayout时,不要在原来的布局文件上改,而是再写一个新的布局文件。
读写文件可以用Context.openFileOutput和Context.openFileInput来访问本应用环境下的文件,还可以用FileInputStream和FileOutputStream访问其他目录下的文件。
SD卡不存在或者写保护怎么用Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)一句就可以搞定吗?不能判断写保护吧!
把xml解析的目标文件放在assets目录下,是不是比放在classpath目录下更好呢?
1.AssetManager am = getAssets();   
2.InputStream file = am.open("introduction.txt");   


sharedPreferences相当于windows系统的注册表
在我的手机上怎么没有data目录,那些写data的程序是否是无法在真实手机上运行呢?


第一次调用SQLiteOpenHelper子类对象的一个getXxxableDatabase方法时,就会创建数据库。
数据库查询时Cursor不需要关闭吗?视频中没有这么做。


android手机中的.properties文件打不开,可以自己做个程序,并在android内部把.properties文件关联到这个程序上。


HttpClient不支持文件上传吗?非得自己写Socket或用HttpURLConnection吗?HttpURLConnection的Bug倒底是什么?(HttpClient支持文件上传)


多线程下载:用HttpURLConnection.getContentLength()获取长度时,不获得整个输入流吗?用监视器工具监视一下。
输入一行或多行内容,效果又怎样呢?
多线程断点下载保存断点位置的代码是不是有缺陷?(每次更新所有线程的下载值。)
在MyView中sleep(60000)看看效果怎样?(没看到ANR),在其onclick事件处理代码中sleep效果又怎样呢?(单击两次时看到了ANR)
在文档的最佳实践(Designing for Responsiveness )中搜索second,将可以看到如下文字:
What Triggers ANR?
In Android, application responsiveness is monitored by the Activity Manager and Window Manager system services. Android will display the ANR dialog for a particular application when it detects one of the following conditions:


?No response to an input event (e.g. key press, screen touch) within 5 seconds
?A BroadcastReceiver hasn't finished executing within 10 seconds




看user guide中的layout,接着看ViewGroup.LayoutParams,接着看android:layout_width,再看layout_width,就可以看到有哪些设置值了。其实,看文档中的Resources Types-->More Types-->Dimension,这些单位的解释就全看到了。




问郭老师,他的onmessage是怎么回事?
TextView的gravity属性设置为“center”表示其文字居中。


EditView未写入文字前,设置其layout_height和layout_width为match_parent,效果如何呢?用如下代码演示EditText的应用:
<EditText
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="abc&#13;&#10;xyz"
    />


看Activity类的api帮助文档,即可看到其生命周期图。长按手机桌面键,又能把先前藏在后台的Activity应用重新调出来,这时候,又要执行其oncreate方法吗?看五子棋又链接网络,好像是这样的。
重新部署Activity应用时,原来的Activity好像与服务器正常断开了连接,这时候是否发生了ondestroy,也就是说在ondestroy时,程序才释放资源?
搜索“程序激活activity”或程序把activity 前台


笔记本电脑不插网线无ip的问题
在XML配置文件中的属性中设置的值"@android:anim/accelerate_decelerate_interpolator"表示R.anim.accelerate_decelerate_interpolator这个常量的值。 


Activity激活另外一个Activity,在第一个Activity中通过Intent传给第二个Activity的Bundle对象,可以通过程序代码getIntent().getExtras()来拿到,这是不是与oncreate()方法中传递过来的bundle是同一个呢?子Activity被返回键隐藏了,是不是就会返回结果给主Activity呢?在子Activity中如何获得请求码呢?被隐藏的Activity如何再用程序激活显示呢?
答:在oncreate中执行   Toast.makeText(this, (savedInstanceState==getIntent().getExtras()) + "", 5).show();显示结果为true,这是因为两个比较的Bundle对象都为null。如果通过程序激活第二个Activity,并且在意图中填充Bundle数据,返回结果就为false了。








看MediaRecorder的API帮助文档,其中就有老黎写的那些代码。
彩信是什么?
系统自己提供的短信广播接收者程序是哪个?我想看其源码改造成对短信分类。看TelephonyProvider程序中的MmsProvider.java,我是在用UtraEdit全局搜索sendBroadcast中看到的。
google搜"android sms icc"和"android smsprovider","android 系统 sms程序 源码"
"android sms程序 源码"
在it315上提供android源码。
http://www.javaeye.com/topic/630188
http://hi.baidu.com/dhqway/blog/item/d32cccd8e4fb863b33fa1c9e.html
google搜索“android 短信 保存到sd卡”:大家都在找短信分类软件呢!http://hiapk.com/bbs/thread-321605-1-1.html




assets目录如何访问?第一种方式是用Context.getAssets()方法返回AssetManager后进行操作。另外,网文“VideoView 没有用过, 不过我在使用WebView 的时候,是这样引用HTML 文件的。 webview.loadUrl("file:///android_asset/JsAlert.html"); ”


android的手机的back键默认行为是finish处于前台的Activity的即Activity的状态为Destroy状态,再次启动该Activity是从onCreate开始的。 而Home键默认是stop前台的Activity即状态为onStop而不是Destroy,若再次启动它,则是从OnResume开始的,即会保持上次Activityd的状态。 back键也有例外的,按back键不会关闭Activity的,比如播放音乐,按了back键之后仍可以继续播放音乐,这是Music这支ap已经重写了back键的事件处理。 为什么需要Home键和Back键呢?一个使得Activity 为Stop一个使得为Destroy呢?我想原因的原因在于是android也是一个多任务的操作系统,通过Home键切换不同的任务,而通过back关闭任务中的某一个活动。若仔细想想就觉得PC的多任务行为一样的。 详细的解说可以看官方文档,也可以看看这文章:http://www.360doc.com/content/09/1201/15/79031_10135626.shtml还有例子 注意:点击Back键后,activity会先去执行finish(), 然后执行onDestroy(); 在乐phone的手机上开发应用,它的左上角有一个“返回”按钮, 如果想在返回后把一些东西销毁掉,可以重写finish()方法。 


 When the user presses the BACK key, the current activity is popped from the stack




可以在环境变量里设置ANDROID_SDK_HOME来指定模拟器的创建和启动目录。
android list avds列出所有avd。


在layout文章中单击 ViewGroup.LayoutParams,就可以看到长度单位。


在xml配置文件中写的"@android:style/Theme.Dialog"对应的是R.style.Theme_Dialog常量吗?能找出出处吗?即使将一个Activity显示为对话框,半遮住后面的Activity,后面的Activity还是无法与用户进行交互。
答:读应用Applying Styles and Themes这篇文档,对样式和主题的很多细节都会非常清楚了。


在程序中声明要使用xxx权限,其目的告诉android系统当前程序需要使用xxx功能,这样,当该程序安装到android系统的手机上时,android系统就会提示用户,告诉用户该程序的风险,让用户决定是否安装。


ppt截取的短信发送和拨号程序的界面从哪来的?
手机上网后,自己有一个ip地址吗?还是只是移动那里有ip与互联网连接,而手机与移动之间
使用无线内部网络协议,或是内部ip。


除了决定意图可以直接通过构造方法进行参数设置外,未决意图的参数也可以通过构造方法设置,例如,new Intent(Intent.ACTION_CALL,Uri.parse("tel:5556"));


布局中可以嵌套布局。


将数据库保存到sdcard.
Sure you can. The docs are a little conflicting about this as they also say that no limitations are imposed. I think they should say that relative paths are to the above location and dbs there ARE private. Here is the code you want:


File dbfile = new File("/sdcard/mydb.sqlite" );  
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null); 
System.out.println("Its open? "  + db.isOpen());


不过要注意加上"android.permission.WRITE_EXTERNAL_STORAGE"访问权限。




看SqliteDatabase.insert方法,进而看insertWithOnConflict,就可以了解到其内部如何根据ContentValues拼凑sql语句和如何处理nullColumnHack列的。


用Context.openOrCreateDatabase()可以在手机内存中创建数据库,SQLiteOpenHelper类调用的就是这个方法。


由下面的代码联想到了父类构造方法在显示赋值之前的原因,否则,这时候就无法用super了。
        Cursor c = new CursorWrapper(myCursor){
        int columnCount = super.getColumnCount()+1;
}


getContentResolver.registerObserver(Uri,true,new ContentObserver(handler){
//如果没有传递handler,这个onchange方法由后台线程调用,否则,由创建handler对象的线程调用。
onchange(){
        }
});


在\sources\base\core\java\android\provider目录下看Telephony.java源码可以获知短信广播的action名称和接收到广播后如何处理短信的代码getMessagesFromIntent方法。
在整个\sources\base\telephony\java\android\telephony目录下搜索sendOrderedBroadcast,就可以了解系统收到短信时发出了怎样的广播。


CursorAdapter中要求数据库中要有一个_id列,这一列被getItemId(int position) 方式使用,ListView.java中会调用这个getItemId方法,作为rowid。


怎样查看android系统内部目前部署了哪些contentprovider?


通过监测Activity的构造方法和统计Activity的实例数,发现每次finish Activity后,ondestroy方法都被调用了。再启动这个Activity的程序,构造方法被调用,Activity的实例数也加1了。这说明Activity每次运行都是在同一个虚拟机中的(或者说是一个进程,这里没考虑空进程被回收的情况)。如果采用adb shell后执行ps和kill命令杀进程,则再次启动这个Activity的程序,虽然构造方法被调用,但是Activity的实例数保持为1,这是因为产生了新进程和新虚拟机,统计实例数的static变量是仅仅是同一个虚拟机中的全局变量。真正操作系统中的全局变量要用sharedPreferences这种机制了,这就是统计软件运行次数的常见做法。


一点想法:文档中说,onSaveInstanceState (Bundle outState)如果被调用,那会发生在onStop之前。onSaveInstanceState什么时候被调用呢?它在非用户故意(用Back键和finish方法)造成的onStop 时调用,以便帮用户在这种意外情况下保存数据,例如,另外一个Activity突然被调用前台时(有办法让电话Activity接到电话时不到前台来吗?即我的Activity总是显示在最前面?),或者通过长按主屏幕菜单打开其他程序。


为什么重新部署五子棋程序的时候,系统能够关闭程序中的Socket呢?


 
mms中的ui包下面的conversationlist.java文件列出所有会话,其布局文件为conversation_list_screen.xml文件。


ComposeMessageActivity.java列出一个会话的所有消息,其布局文件为layout\compose_message_activity.xml,根据布局文件中用到了MessageListView类,在ComposeMessageActivity.java搜索MessageListView,--》mMsgListView--》mMsgListAdapter --》mMsgListAdapter.changeCursor(看取cursor)-->cursor-->AsyncQueryHandler-->MESSAGE_LIST_QUERY_TOKEN-->mBackgroundQueryHandler.startQuery(-->conversationUri就可以知道访问的ContentProvier的url地址
又从mMsgListAdapter--》MessageListAdapter(看取字段)-->bindView方法,了解字段绑定情况。看看simplecursoradapter的源码,即可知道该如何使用bindView方法了。


content://mms-sms/conversations/3


关于发出去的短信地址显示为me:,而接受的短信地址则显示对方电话或姓名的研究:
MessageListAdapter.java类中查找bindView方法(其中也有一个MessageUtils.getLocalNumber()代码来得到自己的手机号),推断出MessageItem类,,然后在MessageItem的构造方法中,有如下一句代码:
 if (!isOutgoingMessage()) 顺藤摸瓜,sms表中的type字段的各个取值的具体含义了:
        public static final int MESSAGE_TYPE_INBOX  = 1;
        public static final int MESSAGE_TYPE_SENT   = 2;
        public static final int MESSAGE_TYPE_DRAFT  = 3;


关于发出的短信显示为白色背景,而接受到的短信显示为亮蓝背景的代码研究:MessageListItem是LinearLayout的子类,用于显示一条短信,它对应的布局文件message_list_item.xml中有如下一句话:android:background="@drawable/listitem_background"
在MessageListItem.java中搜索listitem_background,可以看到如下代码:
           case Mms.MESSAGE_BOX_INBOX:
                mMsgListItem.setBackgroundResource(R.drawable.listitem_background_lightblue);




ListView与cursor绑定后,cursor不关闭的问题,把cursor做成全局的,并交给Activity管理(startManagingCursor),调用cursor的requery方法重新查询,或者mMsgListAdapter.changeCursor(cursor);  或者在每次查询到新的cursor后,接着覆盖ListView的dispatchDraw()方法,并在其中关闭cursor。或者,将数据库的cursor转换成自定义cursor,例如com.android.common.ArrayListCursor(在SmsProvider.java中看到了其应用),然后再关闭数据库Cursor和将自定义Cursor绑定到ListView。


要把 anroid自己提供的例子apidemos跑起来,首先建一个工程为apidemos2,删除原来的内容后,导入所有内容,发现这个有错误。然后再建立一个apidemos工程,先从apidemos2导入AndroidManifest.xml清单文件,对其瘦身到不报错误为止,然后导入资源文件,注意最先导入values和drawable相关包,...,最后导入layout包和xml包。(新建工程,把所有无关内容删除干净,再逐一导入所有内容,没有报错,直接通过)。




在WebView中显示页面的源码,百度“android webview html”
http://hi.baidu.com/czh0221/blog/item/7cca610eb8a448da7acbe135.html


APIDemos中的,文本框具有焦点和不具有焦点时,长按弹出的快捷菜单内容不一样。


在layout.xml文件中,输入android:,怎么不提示android:layout_width之类的属性呢?其他一些属性能够提示。可能是没上网的缘故吧。
还有,设置xml editor的split multiple attribute each on a new line属性,怎么没有立即看到换行的效果?这样设置以后,还要对xml文件再按下ctrl+shift+f进行格式化。


我拿榔头砸电脑,算谁干的?榔头,我?应用程序相当于用户使用的一个工具。服务程序不需要用户登录进来,那它代表谁呢?每个程序运行时都代表某个帐户在干活。
你只有程咬金的三板斧,很多人熬不过这三板,所以,认为程咬金世界第一。


两个android应用,它们的包名定义成了一样,当a应用运行后,b应用就部署不上去了,说本应用已经在前台运行了。还有,在android系统中编写的tcpserver,可以用adb shell连上去,然后运行netstat看服务器是否在此端口上监听,然后exit退出shell。
用adb forward tcp:3333 tcp:7979将pc机的连接请求转发给了emulator中的tcpserver程序。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值