@guhuizaifeiyang
2015-10-29T18:12:41.000000Z
字数 71729
阅读 2480
Android开发
JAVA学习
1 学习Ubuntu常用命令。
2 熟悉eclipse程序使用界面。
3 学习Git常用命令,并将每日工作总结保存到repository,通过Git来管理工作总结。
1 学习JAVA基础。
2 编译ANDROID源码。
执行全编译时,输入source build/envsetup.sh,显示“bash: build/envsetup.sh: 没有那个文件或目录”。
* 原因:没有CD到源码所在目录。
* 解决方案:cd ~/Pro/5030/baseline切换到build/envsetup.sh的所在目录。
1 熟悉Android源码目录结构。
2 Android应用开发详解/Android中的资源访问。
1 Android应用开发详解/Android用户界面。
P97 /widget(spinner)/下拉列表项数组/ String[] str = {"CEO","CFO","PM"}
;
eclipse中,从外部导入工程,中文显示乱码。
ERROR: Application does not specify a android.test.InstrumentationTestRunnerinstrumentation or does not declare uses-library android.test.runner。
出现错误的原因可能是:AndroidManifest.xml配置错误。
解决:1、在<application>
增加引用android.test.runner的声明
<!-- 在本应用中导入需要使用的包,放在application里面activity外面 -->
<uses-library android:name="android.test.runner" />
2、然后在<manifest>
中增加instrumentation的信息说明
<!-- 记住这个一要放在application外面,不然会出现配置错误 信息 -->
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="hb.learn.junit"
android:label="Tests for My App" />
2 烧机
3 adb的使用
4 Log.d()的使用,可以用来过滤log信息,跟踪程序
1 软件测试概述培训
2 Android开发环境培训
3 动手编写Android CommonWidget.apk
* 从MainActivity跳转到ResultActivity时,程序stopped。
原因:have you declared this activity in your AndroidManifest.xml?
解决:将ResultActivity写进AndroidManifest.xml
4 git format-patch
* 在用git am提交patch时,有时在提交失败后,继续提交时会出现/.git/rebase-apply still exists but mbox given错误。
原因:错误的提交导致git内部的数据出现了错误。
解决:使用git am --abort命令将git的状态恢复后就可以继续提交patch了。
1 软件黑盒测试评估规范
2 Android 基本组件练习
* The method setOnClickListener(View.OnClickListener) in the type View is not applicable for
the arguments (new OnClickListener(){})
解决:把 import android.content.DialogInterface.OnClickListener; 改成 import android.view.View.OnClickListener;
* saveB = (Button).findViewById(R.id.button);提示Button cannot be resolved to a variable
原因:(Button)后面多写了个.
解决:改成saveB = (Button)super.findViewById(R.id.button)或saveB = (Button)findViewById(R.id.button);
3 eclipse调试
1 配置管理培训
2 Android[timePicker/DatePicker]
* 按照源码编写程序正常运行,但再移动layout文件中组件的位置后,再Run出现"Unfortunately,timePicker has stopped"
原因:不明
解决:未知
3 Android基于监听器的事件处理:OnClickListener/OnCheckChangeListener/OnItemSelectedListener/OnFocusChangeListener/OnLongClickListener/OnTouchListener
1 客户软件需求管理程序培训
2 党组织关系转移
3 Android[ListView/AlertDialog/DatePickDialog/ProgressDialog/SeekBar/RatingBar/Toast/ImageSwitcher&Gallery/Switch&ToggleButton]
* 设置监听事件还非常生疏。
* intent.setType("vnd.android.cursor.item/phone")字符串常量如何写?改成其它字符串常量之后APP运行stopped。
1 Android Intent
* Intent的Action属性
* Intent的Data属性
* Intent的Category属性
* Intent的Extras属性
* 系统标准Activity Action应用
* 隐式查找:通过Intent Filter实现
* 6.3 1.Action测试---> <intent-filter>***</intent-filter>中,如果漏写<category **/>,则无法通过Action测试。
原因:在Intent对象中出现的Category属性在Intent Filter中必须出现,否则不能通过测试。其中"android.intent.category.DEFAULT"属性是启动Activity默认的属性,这个必须添加,否则Category测试失败。
2 Android短信模块分析之Mms功能
* 查找Massaging>>Setting的Activity文件,并尝试修改。
1、打开Massaging>>Setting。
2、输入adb logcat ActivityManager:I *:s 显示Displayed Displayed com.android.mms/.ui.SettingListActivity
3、在Packages/apps/Mms/src/com/android/mms/ui目录下找到SettingListActivity.java文件
3 adb uninstall
* 删除系统应用:adb uninstall com.android.mms 出现Failure [DELETE_FAILED_INTERNAL_ERROR]
删除自安装应用:adb uninstall com.example.timepicker Success
4 打开flash_tool烧机工具
1、在终端中进入flash_tool所在目录,输入sudo ./flash_tool.sh
2、Scatter-Loading:/out/target/product/s5030/MT6580_Android_scatter.txt
3、选择Firmware Upgrade
1 Android系统应用(Mms)修改
1、修改源码(.java .xml等)
2、AOSP编译Mms模块
3、如果需要永久修改,则adb shell进入到./system/priv-app/Mms下删除Mms.apk。然后adb push将out目录中Mms.apk复制到手机system/priv-app/Mms/。
4、如果不需要永久修改(开机后恢复),则直接adb install -r ./out/target/product/s5030/system/priv-app/Mms/Mms.apk (注:如果不加-r(指重新安装),会出现Failure [INSTALL_FAILED_ALREADY_EXISTS]错误)
2 导入Android源码Project
1、new->project->select General下的Project->Next->输入Project name(和源码Project相同)和Location(源码位置)
* 导入的源码无法修改,出现错误This compilation unit is not on the build path of a java project.
解决:重新导入后未出现该问题。
1 共基线开发指南培训
2 Android第一行代码
*掌握部分:
1、向下一个活动传递数据
2、创建菜单项
3、保存活动被回收时的临时数据
4、活动的生命周期
5、四种布局
6、单位和尺寸
*未掌握部分:
1、创建自定义控件
2、创建自定义适配器
3、LayoutInflater
4、ViewHolder
1 android实战一(ListView)
2 Android第一行代码(第9章 Service)
* Eclipse workspace is in use or cannot be created, choose a different one错误。
原因:workspace配置文件中出现了.lock文件(workspace/.metadata/.lock),锁定了workspace。
解决:删除.lock文件
3 Google Android SDK
* 3.10 不同Activity之间的数据传递——Bundle对象的实现
intent.getExtras()和intent.getBundleExtra()的区别?
intent.putExtras()和intent.putExtra()的区别?
答:intent.putExtras(bundle)和intent.getExtras()配套使用;
intent.putExtra("TAG",bundle)和intent.getBundleExtra("TAG")配套使用
1 Android应用程序培训
2 Pinoy项目之音乐播放器开发。进度:界面基本雏形
1 Android应用界面培训
2 手机基带基础知识培训
3 Pinoy_MediaPlayer:添加MediaPlayerReceiver
* 监听PHONT_STATE和NEW_OUTGOING_CALL,当来电时onpause()->onstop()。再进入程序onResume,点击play则继续播放;锁屏和HOME响应过程类似。
1 Pinoy:添加Notification
2 SDK文档:MediaPlayer(android.media)、Handler(android.os)
3 List和ArrayList的区别
1 Pinoy_MediaPlayer:添加了Handler多线程处理play/pause,stop和焦点事件监听。
* 从Notification重新回到Activity,重新启动了Activity,而不是原来的Activity。
原因:运行了onCreate()
解决:创建Notification对象后,添加
Intent intent = new Intent(this,MediaPlayerActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
2 Pinoy_MediaPlayer:添加Gallery(尚未完成)
3 Pinoy_MediaPlayer:将Notification设置为常驻通知。
* 添加notification.flags = Notification.FLAG_ONGOING_EVENT;
4 Pinoy_MediaPlayer:播放其他音乐应用时,该MediaPlayer应该pause,改变焦点。
当其他音乐应用OnDestroy时,MediaPlayer应该play,重新获得焦点。
* 监听case AudioManager.AUDIOFOCUS_LOSS:
然后将音乐pasue。
监听case AudioManager.AUDIOFOCUS_GAIN:
然后将音乐start
onDestroy()中应该释放焦点:mAudioManager.abandonAudioFocus(mAudioFocusListener);
5 Pinoy_MediaPlayer:禁止横屏
* 在AndroidManifest.xml文件中<activity下面加入
android:screenOrientation="portrait"
6 Pinoy_MediaPlayer:MediaPlayer在播放的时候,按back键应该继续播放。
*Override onKeyDown方法
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode==KeyEvent.KEYCODE_BACK && myPlayer.isPlaying()){
moveTaskToBack(false);
return true;
}
return super.onKeyDown(keyCode, event);
}
// moveTaskToBack(false)当有多个Activity时,按back则不会跳转。改为true则直接跳到桌面,类似于最小化;
1 Pinoy_Gallery:实现图片浏览,上方显示缩略图,下方显示图片。
2 Pinoy_Gallery:进入程序时,应自动更新图片。
* 将读取文件方法写入onResume()
3 Pinoy_Gallery:读取图片格式文件
* List<String> fileList = new ArrayList<String>();
File fileDir = new File(strPath);
File[] files = fileDir.listFiles();
if(files!=null){
for(File file:files){
String fileName = file.getName();
if(fileName.endsWith(".jpg")||fileName.endsWith(".png")||fileName.endsWith(".bmp")){
fileList.add(file.getPath());
}
}
}
4 Pinoy_Gallery:进入程序时,显示第一张图片
5 Pinoy_Gallery:需要增加简单动画效果。滑动图片时,图片能左右拖动。
6 Pinoy_Gallery:图片缩略图随图片一起滑动
* Gallery.setSelection(int Position)
7 Pinoy_Gallery:进入程序时读取图片文件,速度比较慢,要采用多线程处理。
* 结果仍旧不理想
1 Pinoy_Reader:实现txt文本阅读
* public class ReaderActivity extends Activity {
private final String TAG = "[HcReader]";
private String fileName;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.readerlayout);
// fileName = this.getIntent().getStringExtra("file");
fileName = "/storage/sdcard0/Bible01-Genesis.txt";
updateView( fileName,"UTF8" );
}
public void updateView( String fileName,String encoding ){
byte[] data = openFile(fileName);
String display = EncodingUtils.getString(data, encoding);
TextView tv = (TextView)findViewById(R.id.tvTxt);
tv.setText(display);
}
public byte[] openFile(String fileName){
try {
File file = new File(fileName);
FileInputStream in = new FileInputStream(file);
int length = (int)file.length();
byte[] temp = new byte[length];
in.read(temp, 0, length);
return temp;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d(TAG, e.toString());
return null;
}
}
}
2 Pinoy_AlarmClock:源码研究
2.1 AlarmManager
2.2 alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi); //设置闹钟
@Override
protected Dialog onCreateDialog(int id) {
Dialog dialog=null;
switch (id) {
case DIALOG_TIME:
dialog=new TimePickerDialog(
this,
new TimePickerDialog.OnTimeSetListener(){
public void onTimeSet(TimePicker timePicker, int hourOfDay,int minute) {
Calendar c=Calendar.getInstance();//获取日期对象
c.setTimeInMillis(System.currentTimeMillis()); //设置Calendar对象
c.set(Calendar.HOUR, hourOfDay); //设置闹钟小时数
c.set(Calendar.MINUTE, minute); //设置闹钟的分钟数
c.set(Calendar.SECOND, 0); //设置闹钟的秒数
c.set(Calendar.MILLISECOND, 0); //设置闹钟的毫秒数
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class); //创建Intent对象
PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0); //创建PendingIntent
//alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi); //设置闹钟
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pi); //设置闹钟,当前时间就唤醒
Toast.makeText(MainActivity.this, "闹钟设置成功", Toast.LENGTH_LONG).show();//提示用户
}
},
cal.get(Calendar.HOUR_OF_DAY),
cal.get(Calendar.MINUTE),
false);
break;
}
return dialog;
}
2.3 PendingIntent.getBroadcast();
* 要得到一个pendingIntent对象,使用方法类的静态方法
getActivity(),getBroadcast(),getService(),分别对应着Intent的3个行为,跳转到一个Activity,打开一个广播组件和打开一个服务组件。
* 主要使用地方和例子:Notofication,SmsManager,AlarmManager
1 Pinoy_AlarmClock:
1.1 Divier分割线
* <style name="Divider">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">1dp</item>
<item name="android:background">?android:attr/listDivider</item>
</style>
1.2 android自带属性:android:textAppearance="?android:attr/textAppearanceSmall"
1.3 pick ring tone:
final LinearLayout ringToneContainer = (LinearLayout) findViewById(R.id.alarm_ringtone_container
ringToneContainer.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
startActivityForResult(intent , 1);
}
});
private AlarmModel alarmDetails;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if(resultCode==RESULT_OK){
switch (requestCode) {
case 1:
alarmDetails.alarmTone = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
TextView txtToneSelection = (TextView)findViewById(R.id.alarm_label_tone_selection);
txtToneSelection.setText(RingtoneManager.getRingtone(this, alarmDetails.alarmTone).getTitle(this));
break;
default:
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
1.4 android:orderInCategory="100"表示item优先级,数值越大,优先级越高。
1.5 CRUD:Create、Retriveve、Update、Delete
Pinoy_AlarmClock:设置固定闹钟名称和铃声
Pinoy_AlarmClock:闹铃响起后按HOME键推出,应设置发送通知。
Pinoy_MediaPlayer:back后无法继续播放,需用Service来实现。
Pinoy_MediaPlayer:改用Service和BroadcastReceiver实现。
Pinoy_MediaPlayer:界面优化
Fragment的学习
1.1 // activity layout must include a container View in which you can insert the fragment.
1.2 All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly. You can define an interface in the Fragment class and implement it within the Activity.
SQLite的学习
Android中string-array数据源使用
SimpleAdapter的学习
SimpleAdapter的核心代码:
for (int i = 0; i < 10; i++) {
Map map = new HashMap();
map.put("PIC", R.drawable.pic);
map.put("TITLE", "Test Title");
map.put("CONTENT", "Test Content");
contents.add(map);
}
SimpleAdapter adapter = new SimpleAdapter(this,
(List>) contents, R.layout.listitem,
new String[] { "PIC", "TITLE", "CONTENT" }, new int[] {
R.id.listitem_pic, R.id.listitem_title,
R.id.listitem_content });
listView.setAdapter(adapter);
adh push文件夹:
android:用getIdentifier()获取资源Id
Pinoy项目:完成属性
重命名快捷键:F2
3.判断字符串数组是否包括目标字符串:
* // decide stringArray contains source string ?
public boolean contains(String[] stringArray, String source){
List<String>tempList = Arrays.asList(stringArray);
if(tempList.contains(source)){
return true;
}else{
return false;
}
}
4.JAVA list排序:
* Collections.sort(list);
* 自定义排序?
5.优化界面布局,将myfaith_list.xml上面的FrameLayout替换为RelativeLayout。
1.List>排序
* /排序算法
public void sort(List<Map<String, Object>> list) {
Collections.sort(list, new Comparator<Map<String, Object>>(){
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
return o1.get("text").toString().compareTo(o2.get("text").toString());
}
});
}
2.合并MyFaith和MyCountry
3.如何修改ListView SimpleAdapter里面的TextView的颜色?
* 自定义Adapter extends BaseAdapter
1.自定义Adapter中的getView没有执行
* 原因:setAdapter 时,首先会执行getCount(),当getCount() 返回的是0时,就不会去执行getView()方法
* 解决:重写getCount()
2.解决listView item 字体颜色无法调整的问题
* 原因:setTextColor(int color):color为int型,而不是color的ID。
* 解决:getResources().getColor(int id)
3.増加音乐文件是否存在的判断。
* File file = new File(strMusicPath);
if(file.exists()){
playMusic();
}else{
Log.d(TAG, "file doesn't exit");
finish();
}
4.如何加载大分辨率图片
* 有时候我们确实会需要加载一些大分辨率的图片,但是对于移动设备而言,哪怕加载能成功那么大的内存也是一种浪费(屏幕分辨率限制),所以就需要想办法把图片按照一定比率压缩,使分辨率降低,以至于又不需要耗费很大的堆内存空间,又可以最大的利用设备屏幕的分辨率来显示图片。这里就用到一个BitmapFactory.Options对象,下面来介绍它。
BitmapFactory.Options为BitmapFactory的一个内部类,它主要用于设定与存储BitmapFactory加载图片的一些信息。下面是Options中需要用到的属性:
inJustDecodeBounds:如果设置为true,将不把图片的像素数组加载到内存中,仅加载一些额外的数据到Options中。
outHeight:图片的高度。
outWidth:图片的宽度。
inSampleSize:如果设置,图片将依据此采样率进行加载,不能设置为小于1的数。例如设置为4,分辨率宽和高将为原来的1/4,这个时候整体所占内存将是原来的1/16。
android获取屏幕的高度和宽度
1、WindowManager wm = (WindowManager) getContext()
.getSystemService(Context.WINDOW_SERVICE);
int width = wm.getDefaultDisplay().getWidth();
int height = wm.getDefaultDisplay().getHeight();
2、WindowManager wm = this.getWindowManager();
int width = wm.getDefaultDisplay().getWidth();
int height = wm.getDefaultDisplay().getHeight();
1.Bundle和Intent
* Bundle对数据进行封装,方便传递。
2.getApplicationContext和getBaseContext
* getApplicationContext() 返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁
Activity.this的context 返回当前activity的上下文,属于activity ,activity 摧毁他就摧毁
getBaseContext() 返回由构造函数指定或setBaseContext()设置的上下文
3.优化Gallery图片加载速度
* public static Bitmap decodeSampledBitmapFromResource(String pathName, int reqWidth, int reqHeight){
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(pathName, options);
options.inSampleSize = calculateInSampleSize(options, reqHeight, reqWidth);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(pathName, options);
}
public static int calculateInSampleSize(BitmapFactory.Options opt, int reqHeight, int reqWidth){
final int height = opt.outHeight;
final int width = opt.outWidth;
int inSampleSize = 1;
if(height > reqHeight || width > reqWidth){
final int halfHeight = height/2;
final int halfWidth = width/2;
while((halfHeight/inSampleSize)>reqHeight && (halfWidth/inSampleSize)>reqWidth){
inSampleSize *= 2;
}
}
return inSampleSize;
}
4.Progress Dialog构造方法
* .ProgressDialog.show(Context context, CharSequence title, CharSequence message, boolean indeterminate)
* Progress Dialog必须要在后台程序运行完毕前,以dismiss()方法来关闭取得焦点(focus)的对话框,否则程序会陷入无限循环中。
5.线程和进程
* 线程和进程的主要差别体现在以下两个方面:
(1)同样作为基本的执行单元,线程是划分得比进程更小的执行单位。
(2)每个进程都有一段专用的内存区域。与此相反,线程却共享内存单元(包括代码和数据),通过共享的内存单元来实现数据交换、实时通信与必要的同步操作。
* 线程的基本用法
(1)class MyThread extends Thread{
@override
public void run(){
}
}
启动线程:new MyThread().start();
(2)class MyThread implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
}
}
启动线程:MyThread myThread = new MyThread();
new Thread(MyThread).start();
(3)new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
}).start();
页面全屏显示:
不显示标题栏:
requestWindowFeature(Window.FEATURE_NO_TITLE);
不显示状态栏:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
ViewFlipper
1.调用系统摄像头Action:
* Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
2.从相册选取图片Action:
* Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
3.优化Gallery图片加载速度
* 进入GalleryActivity时,先将图片黑底显示,再用子线程更新图片。
问题:可能是逻辑问题,UI更新后没有显示出图片黑底,直接运行了子线程。
4.使用用AsyncTask
* 由于AsyncTask是一一个抽象类,所以如果我们想使用用它,就必须要创建一一个子子类去继承它。在继承时我们可以为AsyncTask类指定三个泛型参数,这三个参数的用用途如下。
1. Params
在执行行AsyncTask时需要传入入的参数,可用用于在后台任务中使用用。
2. Progress
后台任务执行行时,如果需要在界面面上显示示当前的进度,则使用用这里里指定的泛型作为进度单位。
3. Result
当任务执行行完毕后,如果需要对结果进行行返回,则使用用这里里指定的泛型作为返回值类型。
因此,一一个最简单的自自定义AsyncTask就可以写成如下方方式:
class DownloadTask extends AsyncTask<Params, Progress, Result> {}
* 一个异步任务的执行一般包括以下几个步骤:
1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。execute(param1,param2,...)
2.onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。params[0],params[1],...
4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。
Handler
重启Ubuntu输入法:
killall ibus-daemon (结束进程)
ibus-daemon -d (重启ibus)
WeakReference: 防止内存泄漏,要保证内存被虚拟机回收。如果你希望能随时取得某对象的信息,但又不想影响此对象的垃圾收集,那么你应该用 Weak Reference 来记住此对象,而不是使用一般的 reference。
调用系统图片浏览器:
BaseAdapter中getView()没有被调用的问题。
MATRIX矩阵动态缩小放大图片来显示
//获得Bitmap的高和宽
int bmpWidth=bmp.getWidth();
int bmpHeight=bmp.getHeight();
//设置缩小比例
double scale=0.8;
//计算出这次要缩小的比例
scaleWidth=(float)(scaleWidth*scale);
scaleHeight=(float)(scaleHeight*scale);
//产生resize后的Bitmap对象
Matrix matrix=new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizeBmp=Bitmap.createBitmap(bmp, 0, 0, bmpWidth, bmpHeight, matrix, true);
dp转px
优化Gallery图片加载速度
文字复制粘贴(undone)
如何将字串 String 转换成整数 int?
A. 有两个方法:
1). int i = Integer.parseInt([String]); 或
i = Integer.parseInt([String],[int radix]);
2). int i = Integer.valueOf(my_str).intValue();
注: 字串转成 Double, Float, Long 的方法大同小异.
2 如何将整数 int 转换成字串 String ?
A. 有叁种方法:
1.) String s = String.valueOf(i);
2.) String s = Integer.toString(i);
3.) String s = "" + i;
获取手机屏幕高度,宽度,密度
1.
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5)
int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240)
2.(recommend)
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
int width = displayMetrics.widthPixels; // 屏幕宽度(像素)
int height = displayMetrics.heightPixels; // 屏幕高度(像素)
float density = displayMetrics.density; // 屏幕密度(0.75 / 1.0 / 1.5)
设定多分辨率支持:AndroidManifest.xml文件中,加入supports-screens节点
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:resizeable="true"
android:anyDensity="true"/>
TypedArray获取颜色或drawable。有没有获取整个drawable数组的方法???
Resources res = getResources();
TypedArray icons = res.obtainTypedArray(R.array.icons);
Drawable drawable = icons.getDrawable(0);
TypedArray colors = res.obtainTypedArray(R.array.colors);
int color = colors.getColor(0,0);
6.文件查找
* # grep ‘energywise’ * #在当前目录搜索带'energywise'行的文件
# grep -r ‘energywise’ * #在当前目录及其子目录下搜索'energywise'行的文件
# grep -l -r ‘energywise’ * #在当前目录及其子目录下搜索'energywise'行的文件,但是不显示匹配的行,只显示匹配的文件
/**
* read the file by line
* @param path path
* @return ArrayList
*/
public static ArrayList<String> readFile(String path) {
mList.clear();
File file = new File(path);
FileReader fr = null;
BufferedReader br = null;
try {
if (file.exists()) {
fr = new FileReader(file);
} else {
Log.d(TAG, "file in " + path + " does not exist!");
return null;
}
br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null) {
Log.d(TAG, " read line " + line);
mList.add(line);
}
return mList;
} catch (IOException io) {
Log.d(TAG, "IOException");
io.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
if (fr != null) {
fr.close();
}
} catch (IOException io) {
io.printStackTrace();
}
}
return null;
}
adb devices no permissions
进入vi(vim)的命令
vi filename :打开或新建文件,并将光标置于第一行首
vi n filename :打开文件,并将光标置于第n行首
vi filename :打开文件,并将光标置于一行首
vi /pattern filename:打开文件,并将光标置于第一个与pattern匹配的串处
vi -r filename :在上次正用vi编辑时发生系统崩溃,恢复filename
vi filename....filename :打开多个文件,依次进行编辑
移动光标类命令
G : 到结尾
gg : 到开头
0 : 到行首
ctrl+4 : 到行尾
h :光标左移一个字符
l :光标右移一个字符
space:光标右移一个字符
Backspace:光标左移一个字符
k或Ctrl p:光标上移一行
j或Ctrl n :光标下移一行
Enter :光标下移一行
w或W :光标右移一个字至字首
b或B :光标左移一个字至字首
e或E :光标右移一个字至字尾
) :光标移至句尾
( :光标移至句首
}:光标移至段落开头
{:光标移至段落结尾
nG:光标移至第n行首
n :光标下移n行
n-:光标上移n行
n
屏幕翻滚类命令
Ctrl u:向文件首翻半屏
Ctrl d:向文件尾翻半屏
Ctrl f:向文件尾翻一屏
Ctrl+b;向文件首翻一屏
nz:将第n行滚至屏幕顶部,不指定n时将当前行滚至屏幕顶部.
插入文本类命令
i :在光标前
I :在当前行首
a:光标后
A:在当前行尾
o:在当前行之下新开一行
O:在当前行之上新开一行
r:替换当前字符
R:替换当前字符及其后的字符,直至按ESC键
s:从当前光标位置处开始,以输入的文本替代指定数目的字符
保存命令
按ESC键 跳到命令模式,然后:
:w 保存文件但不退出vi
:w file 将修改另外保存到file中,不退出vi
:w! 强制保存,不推出vi
:wq 保存文件并退出vi
:wq! 强制保存文件,并退出vi
:q 不保存文件,退出vi
:q! 不保存文件,强制退出vi
:e! 放弃所有修改,从上次保存文件开始再编辑
调用系统HTML Viewer打开文档
Intent intent = new Intent(Intent.ACTION_VIEW);
File f=new File("/storage/sdcard0/Vote/Admin_2013_01_02_15_16_01.txt");
intent.setDataAndType(Uri.fromFile(f), "text/html");
startActivity(intent);
Source Insight
调用系统闹钟
Intent intent = new Intent();
intent.setAction("android.intent.action.SET_ALARM");
startActivity(intent);
《Android第一行代码》
10.2.1 使用HttpURLConnection
1.获取HttpURLConnection实例:
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
2.设置HTTP请求所使用的方法:GET和POST
connection.setRequestMethod("GET");
3.自由定制
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
4.获取服务器返回的输入流
InputStream in = connection.getInputStream();
5.关闭HTTP连接
connection.disconnect();
10.2.2 使用Httpclient
1.创建一个DefaultHttpClient的实例
HttpClient httpClient = new DefaultHttpClient();
2.发起一条GET请求
HttpGet httpGet = new HttpGet("http://www.baidu.com");
httpClient.execute(httpGet);
3.Or 发起一条POST请求
HttpPost httpPost = new HttpPost("http://www.baidu.com");
List params = new ArrayList();
params.add(new BasicNameValuePair("username", "admin"));
params.add(new BasicNameValuePair("password", "123456"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8");
httpPost.setEntity(entity);
httpClient.execute(httpPost);
4.取出服务返回的具体内容
if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 请求和响应都成功了
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity, "utf-8");
parseJSONWithGSON(response);
}
寻找类快捷键Ctrl+Shift+T
ViewFlipper:屏幕切换
Serializable
当java内存有一个对象的时候,我们想把它持久化保存起来,以后又可以从保存的数据中恢复成对象,这种情况经常在java中出现;sun公司为了方便实现这种功能,为用户提供了java.io.Serializable这个接口,这个接口中没有方法(又称为mini接口);
将对象保存到输出流中
Student stu = new Student(981036, "LiuMing", 18, "CSD");
FileOutputStream fo = new FileOutputStream("data.ser");
ObjectOutputStream so = new ObjectOutputStream(fo);
try {
so.writeObject(stu);
so.close();
} catch (IOException e) {
System.out.println(e);
}
读取一个对象
FileInputStream fi = new FileInputStream("data.ser");
ObjectInputStream si = new ObjectInputStream(fi);
try {
stu = (Student) si.readObject();
si.close();
} catch (IOException e)
{
System.out.println(e);
}
7.自定义View必须要重写三个构造函数:
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyView(Context context, AttributeSet attrs) {
super(context);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context);
}
android sd卡路径正确获取 双sd卡获取(见Pinoy中的SDCardScanner类)
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder viewHolder;
if(convertView == null){
convertView = LayoutInflater.from(myContext).inflate(resourceId, null);
viewHolder = new ViewHolder();
viewHolder.name = (TextView)convertView.findViewById(R.id.tvTitleItem);
viewHolder.image = (ImageView)convertView.findViewById(R.id.ivIconItem);
viewHolder.pos = position;
convertView.setTag(viewHolder);
}else
{
viewHolder = (ViewHolder) convertView.getTag();
}
textTile = listViewItems.get(position).get("text").toString();
textColor = listViewItems.get(position).get("textColor").toString();
viewHolder.name.setText(textTile);
viewHolder.name.setTextColor(myContext.getResources().getColor(Integer.parseInt(textColor)));
new DownloadAsyncTask().execute(viewHolder);
// viewHolder.image.setImageResource(Integer.parseInt(listViewItems.get(position).get("img").toString()));
return convertView;
}
private static class ViewHolder{
public TextView name;
public ImageView image;
public int pos;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return listViewItems.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return listViewItems.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
private class DownloadAsyncTask extends AsyncTask<ViewHolder, Void, ViewHolder> {
@Override
protected ViewHolder doInBackground(ViewHolder... params) {
// TODO Auto-generated method stub
//load image directly
ViewHolder viewHolder = params[0];
return viewHolder;
}
@Override
protected void onPostExecute(ViewHolder result) {
// TODO Auto-generated method stub
int position = result.pos;
result.image.setImageResource(Integer.parseInt(listViewItems.get(position).get("img").toString()));
}
}
* 不过最后发现,加载速度慢的主要原因是图片加载错了,换成小尺寸的即可。
android:label:静态修改title
application里设置了此标签,其他activity没有设置的情况下,应用程序名在桌面上的名字和所有activity的title是这个设置的标签
application里设置了此标签,主activity中也设置了此标签,则应用程序名和主activity的title都是主activity中设置的标签,其他非主activity的title如果没有自己设置此标签,还是使用application中设置的标签,如果其他非主activity也设置了此标签,则其title就是自己设置的这个标签
getActionBar().setTitle();动态修改title
Notification.FLAG_ONGOING_EVENT标志位可以让Notification成为持续或正在进行的Notification(即非一闪而过)。
Notification.FLAG_NO_CLEAR标志位可以让Notification常驻任务栏;
Intent.FLAG_ACTIVITY_NEW_TASK:当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的taskAffinity属性进行匹配,如果找到一个task的taskAffinity与之相同,就将目标Activity压入此task中,如果查找无果,则创建一个新的task,并将该task的taskAffinity设置为目标Activity的taskActivity,将目标Activity放置于此task。注意,如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的Activity之间的跳转使用这个标记是没有意义的,因为当前应用task就是目标Activity最好的宿主。见:http://blog.csdn.net/liuhe688/article/details/6761337
FLAG_ACTIVITY_SINGLE_TOP:当task中存在目标Activity实例并且位于栈的顶端时,不再创建一个新的,直接利用这个实例。
Activity
6.1 Activity一共有以下四种launchMode:
1.standard:跳转时系统都会在task中生成一个新的FirstActivity实例,并且放于栈结构的顶部.
2.singleTop:跳转时系统会先在栈结构中寻找是否有一个FirstActivity实例正位于栈顶,如果有则不再生成新的,而是直接使用。
3.singleTask:如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。
4.singleInstance:(最为复杂)
release version要修改android:versionName
android setLayoutparams
问题:在用ivTop.setLayoutParams(new RelativeLayout.LayoutParams())修改控件的大小后,发现控件属性不再受XML文件影响。
“Set the layout parameters associated with this view. These supply parameters to the parent of this view specifying how it should be arranged. There are many subclasses of
ViewGroup.LayoutParams, and these correspond to the different subclasses of ViewGroup that are responsible for arranging their children.
”
* 实例:
RelativeLayout.LayoutParams layoutParams= new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
view.setLayoutParams(layoutParams);
menu
option menu图标为正方形时,显示正常。长方形图片会缩小。
the sizes of menu icons are:
logo图尺寸为77*190,屏幕为hdpi,所以缩小了。
Didn't find class "com.tinno.pinoy.MainActivity" on path: DexPathList错误
下载git repo代码
3.1 mkdir
3.2 repo init -u git@192.168.10.207:mt6753/platform/manifest.git -b sw -m ALPS.L1.MP3.V2.21_TINNO6753_65C_G_KERNEL_SW1_V1.1.xml
3.3 repo sync
SQLiteOpenHelper的使用方法
所有继承了这个类的类都必须实现下面这样的一个构造方法:
public DatabaseHelper(Context context, String name, CursorFactory factory, int version)
第一个参数:Context类型,上下文对象。
第二个参数:String类型,数据库的名称
第三个参数:CursorFactory类型
第四个参数:int类型,数据库版本
SQLiteDatabase的常用方法
openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory)
打开或创建数据库
insert(String table,String nullColumnHack,ContentValues values)
添加一条记录
delete(String table,String whereClause,String[] whereArgs)
删除一条记录
query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy)
查询一条记录
update(String table,ContentValues values,String whereClause,String[] whereArgs)
修改记录
execSQL(String sql)
执行一条SQL语句
close()
关闭数据库
切换java版本
下载网络图像
private static Bitmap getBitmapFromUrl(String urlString) {
Bitmap bitmap;
InputStream is = null;
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
is = new BufferedInputStream(conn.getInputStream());
bitmap = BitmapFactory.decodeStream(is);
conn.disconnect();
return bitmap;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
}
return null;
}
《android群英传》http://blog.csdn.net/column/details/synctask.html
3.1 Android异步加载全解析之开篇瞎扯淡
3.2 Android异步加载全解析之使用多线程
3.3 Android异步加载全解析之使用AsyncTask
3.4 Android异步加载全解析之大图处理
3.5 Android异步加载全解析之引入一级缓存
3.6 Android异步加载全解析之引入二级缓存
3.7 Android异步加载全解析之IntentService
3.8 Android异步加载全解析之Bitmap
touch命令:创建文件
remote repository
■git clone
$ git clone http[s]://example.com/path/to/repo.git/
$ git clone ssh://example.com/path/to/repo.git/
$ git clone git://example.com/path/to/repo.git/
$ git clone /opt/git/project.git
$ git clone file:///opt/git/project.git
$ git clone ftp[s]://example.com/path/to/repo.git/
$ git clone rsync://example.com/path/to/repo.git/
■git remote
1. git remote:命令列出所有远程主机。
2. git remote -v:查看远程主机网址
3. git clone -o jQuery https://github.com/jquery/jquery.git:将远程主机命名为jQuery
4. git remote show <主机名>:查看该主机的详细信息。
5. git remote add <主机名> <网址>:添加远程主机。git remote add remoteRepo android@172.16.21.27:/home/android/remoteRepo
6. git remote rm <主机名>:删除远程主机。
7. git remote rename <原主机名> <新主机名>:远程主机的改名。
■git fetch:将远程主机更新取回本地
1. git fetch <远程主机名>:将某个远程主机的更新,全部取回本地。
2. git fetch <远程主机名> <分支名>:取回特定分支的更新。
■git pull:取回远程主机某个分支的更新,再与本地的指定分支合并。
1. git pull <远程主机名> <远程分支名>:<本地分支名>
2. git pull -p:在本地删除远程已经删除的分支。
■git push
1. git push <远程主机名> <本地分支名>:<远程分支名>
2. git push:如果当前分支只有一个追踪分支,那么主机名都可以省略。
3. git push origin:将当前分支推送到origin主机的对应分支。
获得包名和类名
setComponent
ComponentName rec = new ComponentName(getPackageName(),
MediaButtonIntentReceiver.class.getName());
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
i.setComponent(rec);
ComponentName是用来打开其他应用程序中的Activity或服务的。
Intent i=new Intent();
i.setComponent(new ComponentName(String packageName,String activityName ));
startActivity(i);
用法二:
Intent中可以直接使用Intent.setClass(),也可以使用组件Component
HandlerThread
介绍:HandlerThread继承自Thread,当线程开启时,也就是它run方法运行起来后,线程同时创建了一个含有消息队列的Looper,并对外提供自己这个Looper对象的get方法,这就是它和普通Thread唯一不同的地方。
用法:
1.开发中如果多次使用类似new Thread(){...}.start()这种方式开启一个子线程,会创建多个匿名线程,使得程序运行起来越来越慢,而HandlerThread自带Looper使他可以通过消息来多次重复使用当前线程,节省开支;
2.android系统提供的Handler类内部的Looper默认绑定的是UI线程的消息队列,对于非UI线程又想使用消息机制,那么HandlerThread内部的Looper是最合适的,它不会干扰或阻塞UI线程。
步骤:
HandlerThread handlerThread = new HandlerThread("leochin.com");
handlerThread.start(); //创建HandlerThread后一定要记得start()
Looper looper = handlerThread.getLooper();
Handler handler = new Handler(looper);
通过以上三步我们就成功创建HandlerThread。通过handler发送消息,就会在子线程中执行。如果想让HandlerThread退出,则需要调用handlerThread.quit();。
应用android自带颜色属性:@android:color/
Your content must have a ListView whose id attribute is 'android.R.id.list'???
解决:
MyActivity exends Activity
在MyActivity的XML布局文件中,
Android SQLite数据库判断某张表是否存在的语句
1、可以在创建表之前判断,这样就不会重新创建,create table if not exists Student(name text primary key, code integer); 比平时多了if not exists
2、
Cursor cursor = db.rawQuery("select name from sqlite_master where type='table';", null);
while(cursor.moveToNext()){
//遍历出表名
String name = cursor.getString(0);
Log.i("System.out", name);
}
3、
String sql = "select count(*) as c from sqlite_master where type ='table' and name ='Student';";
cursor = db.rawQuery(sql, null);
if(cursor.moveToNext()){
int count = cursor.getInt(0);
if(count>0){
result = true;
}
}
db = dbHelper.getReadableDatabase();
Cursor c = db.query(Alarm.TABLE_NAME, null, null, null, null, null, null);
Log.d(TAG, "c count: "+c.getCount());
if(c.getCount()>0){
return;
}else{
}
ExpandableListView
Android 之SparseArray:SparseArray是android里为这样的Hashmap而专门写的class,目的是提高效率,其核心是折半查找函数(binarySearch)
AlarmManager.set()设置闹钟精确度
getApplicationContext():返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁
OnClickListener
在一个Service中启动一个Acitivity:加上 FLAG_ACTIVITY_NEW_TASK
代码:
Intent dialogIntent = new Intent(getBaseContext(), YourActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(dialogIntent);
// 或者隐式启动
Error: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.
解决: dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ubuntu输入法 没有输入窗口
ActionBar custom
ActionBar actionbar = getActionBar();
actionbar.setBackgroundDrawable(getResources().getDrawable(R.color.main_background_color));
actionbar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM );
LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
ViewGroup view = (ViewGroup) inflater.inflate(R.layout.actionbar_main, null);
actionbar.setCustomView(view);
share action
Intent intentShare = new Intent(android.intent.action.SEND);
intentShare.setType("audio/*");
startActivity(intentShare);
彩信/邮件分享
find
使用格式 : find [指定查找目录] [查找规则] [查找完后执行的action]
find . -name "*.cpp" | xargs grep 'efg':在当前目录下所有.cpp文件中查找efg函数
xargs展开find获得的结果,使其作为grep的参数
1.使用name选项:
想要在自己的根目录
find ~ -name "*.log" -print
想要在当前目录及子目录中查找所有的‘ *.log‘文件,可以用:
find . -name "*.log" -print
不想要在当前目录及子目录中查找所有的‘ *.log‘文件,可以用:
find . ! -name "*.log" -print
想要的当前目录及子目录中查找文件名以一个大写字母开头的文件,可以用:
find . -name "[A-Z]*" -print
想要在/etc目录中查找文件名以host开头的文件,可以用:
find /etc -name "host*" -print
想要查找$HOME目录中的文件,可以用:
find ~ -name "*" -print 或find . -print
要想让系统高负荷运行,就从根目录开始查找所有的文件。
find / -name "*" -print
如果想在当前目录查找文件名以一个个小写字母开头,最后是4到9加上.log结束的文件:
find . -name "[a-z]*[4-9].log" -print
将文件路径作为一个整体进行匹配
fine . -path "*tinno/pinoy"
过淲掉所有.xml文件
find . \( -name ".xml" -prune \) -o -name "*Activity*"
只在目录中递归搜索所有的.c和.cpp文件:
$ grep "main()" . -r --include *.{c,cpp}
在搜索中排除所有的README文件:
$ grep "main()" . -r --exclude "README"
使用-mindepth参数设置最小深度,使用-maxdepth参数设置最大深度:
$ find . -maxdepth 1 -type f -print
2.-a 连接两个不同的条件(两个条件必须同时满足)
3.-o 连接两个不同的条件(两个条件满足其一即可)
find . ( -name ".txt" -o -name ".pdf" ) -print
4.根据文件类型来查找文件
-type
f // 普通文件
d //目录文件
l //链接文件
b //块设备文件
c //字符设备文件
p //管道文件
s //socket文件
5.根据大小来查找文件
-size
#find /tmp -size 2M //查找在/tmp 目录下等于2M的文件
#find /tmp -size +2M //查找在/tmp 目录下大于2M的文件
#find /tmp -size -2M //查找在/tmp 目录下小于2M的文件
6.xargs命令:应该紧跟在管道操作符之后。它以标准输入作为主要的源数据流。
用-d选项为输入指定一个定制的定界符
$ echo "split.split.split.split" | xargs -d . -n 2
split split
split split
查看IP:ifconfig
create Spinner(file:///home/android/Adt-eclipse/sdk/docs/guide/topics/ui/controls/spinner.html)
1. add Spinner in XML:
<Spinner
android:id="@+id/planets_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
2. define an string array in a string resource file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="planets_array">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
<item>Mars</item>
<item>Jupiter</item>
<item>Saturn</item>
<item>Uranus</item>
<item>Neptune</item>
</string-array>
</resources>
3. supply the spinner with the array using an instance of ArrayAdapter:
Spinner spinner = (Spinner) findViewById(R.id.spinner);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.planets_array, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
4. an implementation of the interface in an Activity:
public class MainActivity extends Activity implements OnItemSelectedListener{
private Spinner mSpinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSpinner = (Spinner)findViewById(R.id.spinner1);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.planets_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(adapter);
mSpinner.setOnItemSelectedListener(this);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), mSpinner.getItemAtPosition(position).toString(), Toast.LENGTH_LONG).show();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO Auto-generated method stub
}
}
throws和throw的区别
throws使用在函数上,是方法可能抛出异常的声明,表示此方法不处理异常,而交给方法的调用处进行处理。。
throw使用在函数内,是语句抛出一个异常。
好的编程习惯:
1.在写程序时,对可能会出现异常的部分通常要用try{...}catch{...}去捕捉它并对它进行处理;
2.用try{...}catch{...}捕捉了异常之后一定要对在catch{...}中对其进行处理,那怕是最简单的一句输出语句,或栈输入e.printStackTrace();
3.如果是捕捉IO输入输出流中的异常,一定要在try{...}catch{...}后加finally{...}把输入输出流关闭;
4.如果在函数体内用throw抛出了某种异常,最好要在函数名中加throws抛异常声明,然后交给调用它的上层函数进行处理。
Gallery_5030 String to Type
public static final int MEDIA_TYPE_IMAGE = 2;
public static final int MEDIA_TYPE_VIDEO = 4;
public static final int MEDIA_TYPE_ALL = MEDIA_TYPE_IMAGE | MEDIA_TYPE_VIDEO;
public static final String MEDIA_TYPE_IMAGE_STRING = "image";
public static final String MEDIA_TYPE_VIDEO_STRING = "video";
public static final String MEDIA_TYPE_ALL_STRING = "all";
public static int getTypeFromString(String s) {
if (MEDIA_TYPE_ALL_STRING.equals(s)) return MediaObject.MEDIA_TYPE_ALL;
if (MEDIA_TYPE_IMAGE_STRING.equals(s)) return MediaObject.MEDIA_TYPE_IMAGE;
if (MEDIA_TYPE_VIDEO_STRING.equals(s)) return MediaObject.MEDIA_TYPE_VIDEO;
throw new IllegalArgumentException(s);
}
public static String getTypeString(int type) {
switch (type) {
case MEDIA_TYPE_IMAGE: return MEDIA_TYPE_IMAGE_STRING;
case MEDIA_TYPE_VIDEO: return MEDIA_TYPE_VIDEO_STRING;
case MEDIA_TYPE_ALL: return MEDIA_TYPE_ALL_STRING;
}
throw new IllegalArgumentException();
}
android中的ellipsize
android:ellipsize = "end" 省略号在结尾
android:ellipsize = "start" 省略号在开头
android:ellipsize = "middle" 省略号在中间
android:ellipsize = "marquee" 跑马灯
最好加一个约束android:singleline = "true"
tv.setEllipsize(TextUtils.TruncateAt.valueOf("END"));
tv.setEllipsize(TextUtils.TruncateAt.valueOf("START"));
tv.setEllipsize(TextUtils.TruncateAt.valueOf("MIDDLE"));
tv.setEllipsize(TextUtils.TruncateAt.valueOf("MARQUEE"));
最好再加一个约束tv.setSingleLine(true);
#!/bin/bash
direc="$1" #$(pwd)
OLDIFS=$IFS
IFS=:
# 以一个文件夹的框架在另一个目录下创建文件夹和空文件
# chmod +x ./my_adb_push.sh #使脚本具有执行权限
# ./my_adb_push.sh <local dir> <remote dir> #执行脚本
# example: ./my_adb_push.sh ./local_dir ./storage/sdcard0/remote_dir
for path in $( find $direc -type d -printf "%p$IFS")
do
echo adb shell mkdir -p "$2/${path:${#direc}+1}"
adb shell mkdir -p "$2/${path:${#direc}+1}"
#adb shell exit
done
IFS=$OLDIFS
#cp -a "%%1" "%%2"
adb push "$1" "$2"
adb push "$1" "$2"
Android之TabHost布局
1.概念
盛放Tab的容器就是TabHost,包含TabWidget和FrameLayout两个部分,TabWidget是每个Tab的标签,FrameLayout是Tab内容。
TabHost的实现有两种方式:
第一种继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost。各个Tab中的内容在布局文件中定义就行了。
* 细节分析:
1.主类继承TabActivity
public class Pagination extends TabActivity
2.获取当前TabHost对象
TabHost tabHost = getTabHost();
3.添加Tab分页标签
tabHost.addTab(tabHost.newTabSpec("Tab1")
.setIndicator("Tab1", getResources().getDrawable(R.drawable.a1))
.setContent(this));
第二种方式,不继承TabActivity,在布局文件中定义TabHost即可,布局:
1、TabHost 必须设置android:id为@android:id/tabhost
2、TabWidget 必须设置android:id为@android:id/tabs
3、FrameLayout 必须设置android:id为@android:id/tabcontent
2.用法
TabHost mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
mTabHost.addTab(TabSpec spec);
3.使用Fragment实现tabhost效果(http://blog.csdn.net/u013412220/article/details/41241855)Project:fragmentdemo
git reset版本前切记要备份
Pinoy->Library:当文本过长时,每一行的首字没有对齐
修改pinoy目录结构,将pinoy目录下的Pinoy和Prayer文件夹置于根目录下.
android:visibility
View.VISIBLE很显然就是可见,View.UNVISIBLE是不是可见,但是在这种情况下它会占据空间。就是说如果控件的android:visibility
设置为View.UNVISIBLE的话,虽然控件隐藏了,但是它还是占着画面中它布局的位置,这一点和C#中的意义不一样。而View.GONE则
是指该控件的不可见,也不占用系统布局中的空间。
android:splitMotionEvents:定义布局是否传递触摸事件(touch)到子布局,true表示传递给子布局,false表示不传递。
Android PagerAdapter的用法
PageAdapter是一个抽象类,直接继承于Object,导入包android.support.v4.view.PagerAdapter即可使用。
要使用PagerAdapter,首先要继承PagerAdapter类,然后至少覆盖以下方法instantiateItem(ViewGroup, int)
/这个方法,return一个对象,这个对象表明了PagerAdapter适配器选择哪个对象放在当前的ViewPager中/
destroyItem(ViewGroup, int, Object)/这个方法,是从ViewGroup中移出当前View/
getCount() /这个方法,是获取当前窗体界面数/
isViewFromObject(View, Object) /这个方法,在帮助文档中原文是could be implemented as return view == object,也就是用于判断是否由对象生成界面/
Music_5030: TabHost+ViewPager
修改客户反馈BUG。主要有:
1、播放音乐时通知栏图标显示不完整。
将图片换成四周空白的图片
2、音乐播放界面Back后,音乐停止。
3、修改闹钟默认时间和格式
4、将默认闹钟在开机启动应用时便写入数据库
Android应用经典主界面框架:仿网易新闻客户端、CSDN 客户端 (Fragment ViewPager)(http://blog.csdn.net/xiaanming/article/details/10766053)
开源控件ViewPagerIndicator的使用
Fragment中获取数据
Android Theme(http://blog.csdn.net/dalancon/article/details/20359535)
2.1 attrs.xml
attrs文件摘要
attrs:这个文件里面放置自定义属性。android自带很多属性,比如我们布局的时候使用的layout_width,layout_height等等,android自带的attrs.xml文件在sdk/platforms/android-版本号/data/res/values/attrs.xml
attrs.xml文件格式:
<declare-styleable name="TextAppearance">
<attr name="android:fontFamily" format=”color”/>
<attr name="android:textAllCaps" />
<attr name="android:textColor" />
每个attr代表一个属性,字段format表示这个属性代表的是哪一种资源
state_pressed、state_focused、state_selected区别:
pressed按下后还未松开,表示按下。再松开后当前控件获得了焦点,是focused,同时也有selected状态,表示选中。
但是选中状态的控件是可以有很多个的,而focused的只有一个,即focused和selected的一个重要区别是,一个窗口只能有一个视图获得焦点focused,而一个窗口可以有很多个视图同时处于选中selected状态。
设置音乐音量为最大音量
AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); // 获取当前音乐音量
int maxVolume = mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);// 获取最大声音
Toast.makeText(getApplicationContext(), "volume: "+mVolume+" max volume: "+maxVolume, Toast.LENGTH_LONG).show();
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume, 0);
android 使用MediaPlayer播放assets目录的音频文件
播放应用的原始资源文件(assets)
1) 通过Context.getAssets()方法获得AssetManager对象
2) 通过AssetManager对象的openFd(String name)方法打开指定的原生资源文件夹,返回一个AssetFileDescriptor对象
3) 通过AssetFileDescriptor的getFileDescriptor()得到一个FileDescriptor对象
4) 通过public void setDataSource (FileDescriptor fd, long offset, long length)来创建MediaPlayer对象
5) 调用MediaPlayer.prepare()方法准备音频
6) 调用MediaPlayer的start()、pause()、stop()等方法控制
AssetFileDescriptor fileDescriptor = this.getAssets()..openFd("a2.mp3");
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),
fileDescriptor.getStartOffset(),
fileDescriptor.getLength());
mediaPlayer.prepare();
mediaPlayer.start();
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);//提示声音音量
Android的对话框有两种:PopupWindow和AlertDialog。它们的不同点在于:(http://blog.csdn.net/tianjf0514/article/details/7570302#)Project:PopUpWindow
AlertDialog的位置固定,而PopupWindow的位置可以随意
AlertDialog是非阻塞线程的,而PopupWindow是阻塞线程的
PopupWindow的位置按照有无偏移分,可以分为偏移和无偏移两种;按照参照物的不同,可以分为相对于某个控件(Anchor锚)和相对于父控件。具体如下
showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移
ButterKnife(http://jakewharton.github.io/butterknife/)
音乐分享增加Facebook
Angelus下的闹钟时间应可以设置
Music > Select song > Set as Ringtone > It should have an option for SIM 1 and SIM 2.
将闹钟列表用RadioGroup实现
}
switch (checkedId) {
case mEnableRadioButton.getId():
break;
default:
break;
}
采用switch来选择radioButton的Id,无法使用.getId()方法
Android Studio import-summary
The following files were not copied into the new Gradle project; you
should evaluate whether these are still needed in your project and if
so manually move them:
Android Gradle projects use a different directory structure than ADT
Eclipse projects. Here's how the projects were restructured:
PINOY闹钟灭屏响起时,需要亮屏
该方法的使用一定要伴随mWakelock.release();否则会报异常;
推荐使用方法:在唤醒屏幕显示的activity的onResume方法中唤醒,在onPause方法中release;
来电铃声响起 PINOY闹钟也响起,两个声音一块.
ExifInterface.TAG_DATETIME
Pinoy中图片显示顺序和系统图库显示顺序不一致
系统图库根据图片日期来显示图片
public long getDateTime(String path) {
try {
ExifInterface exifInterface = new ExifInterface(path);
String dateTimeString = exifInterface.getAttribute(ExifInterface.TAG_DATETIME);
if (dateTimeString == null) return -1;
ParsePosition pos = new ParsePosition(0);
SimpleDateFormat sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
try {
Date datetime = sFormatter.parse(dateTimeString, pos);
if (datetime == null) return -1;
return datetime.getTime();
} catch (IllegalArgumentException ex) {
Log.e(TAG, "getDateTime: IllegalArgumentException!", ex);
return -1;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return -1;
}
Android多媒体- ExifInterface读取图片相关信息
Android Studio安装后Fetching android sdk component information超时的解决方案
Android Studio安装完成后,如果直接启动,Android Studio会去获取 android sdk 组件信息,这个过程相当慢,还经常加载失败,导致Android Studio启动不起开。解决办法就是不去获取android sdk 组件信息。
解决方法:
1)进入刚安装的Android Studio目录下的bin目录。找到idea.properties文件,用文本编辑器打开。
2)在idea.properties文件末尾添加一行:disable.android.first.run=true,然后保存文件。
3)关闭Android Studio后重新启动,便可进入界面。
Android Studio常见错误之:Rendering Problems/The following classes could not be instantiated
study Android_Universal_Image_Loader
String数组转List,List转String数组
List list = new ArrayList();
list.add("a1");
list.add("a2");
String[] toBeStored = list.toArray(new String[list.size()]);
for(String s : toBeStored) {
System.out.println(s);
}
String[] arr = new String[] {"1", "2"};
List list = Arrays.asList(arr);
使用Universal-Image-Loader框架不仅可以加载网络图片,还可以加载sd卡中的图片,Content provider等
//图片来源于Content provider
String contentprividerUrl = "content://media/external/audio/albumart/13";
//图片来源于assets
String assetsUrl = Scheme.ASSETS.wrap("image.png");
//图片来源于
String drawableUrl = Scheme.DRAWABLE.wrap("R.drawable.image");
AndroidStudio创建项目时一直处于building“project name”gradle project info的解决办法
查看gradle版本:查看目录C:\Users\用户名.gradle\wrapper\dists\gradle-1.XX-all
存放位置:C:\Users\用户名.gradle\wrapper\dists\gradle-1.XX-all\3jdgemv0iv8uqohg3kcp2o88r1\gradle-1.XX-all.zip
知道了版本,知道了位置,剩下的就是在网上下载离线包了,搜索gradle-1.XX-all.zip,我的版本为gradle-1.10-all下载完毕后直接把zip拷贝到C:\Users\用户名.gradle\wrapper\dists\gradle-1.XX-all\3jdgemv0iv8uqohg3kcp2o88r1\ 下即可。重启Android Studio后,打开项目即可。
android studio如何导入android-support-v7-appcompat包
第一步在module上右击,选择 open module settings
Dependencies
gitHub/DynamicCardLayout
Android getMeasuredHeight()与getHeight()的区别
getMeasuredHeight()返回的是原始测量高度,与屏幕无关,getHeight()返回的是在屏幕上显示的高度。实际上在当屏幕可以包裹内容的时候,他们的值是相等的,只有当view超出屏幕后,才能看出他们的区别。当超出屏幕后,getMeasuredHeight()等于getHeight()加上屏幕之外没有显示的高度。
1 mScrollView.getChildAt(0).getMeasuredHeight()表示:
ScrollView所占的高度.即ScrollView内容的高度.常常有一
部分内容要滑动后才可见,这部分的高度也包含在了
mScrollView.getChildAt(0).getMeasuredHeight()中
*
2 view.getScrollY表示:
ScrollView顶端已经滑出去的高度
*
3 view.getHeight()表示:
Application context
方法是创建一个属于你自己的android.app.Application的子类,然后在manifest中申明一下这个类,这是 android就为此建立一个全局可用的实例,你可以在其他任何地方使用Context.getApplicationContext()或Context.getApplication方法方法获取这个实例,进而获取其中的状态(变量)。
MyApplication mApplication = (MyApplication)getApplication();
Activity context
Android中资源文件夹res/raw和assets的使用
*res/raw和assets的相同点:
1.两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
*res/raw和assets的不同点:
1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
2.res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹
*读取文件资源:
1.读取res/raw下的文件资源,通过以下方式获取输入流来进行写操作
[java] view plaincopy
InputStream is = getResources().openRawResource(R.id.filename);
2.读取assets下的文件资源,通过以下方式获取输入流来进行写操作
[java] view plaincopy
AssetManager am = null;
am = getAssets();
InputStream is = am.open("filename");
修复菲律宾5460_V4客户反馈问题
vi/vim使用进阶: 目录(http://blog.csdn.net/kingchan/article/details/6729800)
菲律宾5420_V5各自模块反馈
Pinoy > Wordstring > Personal Prayers > Change Choosen to Chosen
Pinoy > Prayer setting > Angelus > Morning, afternoon, and evening angelus, wordstring should be Angelus
Pinoy > Prayer setting should be enabled as default.
Pinoy > Intercession Prayers> Change the Holy Spirit to The Holy Spirit
Pinoy > my|country > Alam mo ba? > Change the wordstring from Gat. Jose Rizal to Rizal from Filipino Heros to Filipino Heroes.
Pinoy > my|country > Gat. Jose Rizal > Add space before the number, after the word Rizal.
Prayer setting> After the Prayer (Morning, Angelus, 3oclock Prayer, Evening Prayer) alarms it will alarm again. After the alarm played, it should stop not loop In playing.
Pinoy > Remove the Set as ringtone function when the use long press the pinoy file.
横竖屏切换不销毁activity
在activity的属性中添加 android:configChanges="orientation|screenSize"
java代码的activity中加入配置信息改动的处理代码
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// 检测屏幕的方向:纵向或横向
if (this.getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE) {
//当前为横屏, 在此处添加额外的处理代码
}
else if (this.getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT) {
//当前为竖屏, 在此处添加额外的处理代码
}
}
gvim菜单乱码问题解决方法
* Ubuntu 10.10 默认安装将会把中文区域设置为zh_CN.utf8,而GVim能识别的中文区域设置为zh_CN.UTF-8。因此GVim会在启动时报错,且 无法正常加载中文菜单。
解决方案: Linux下编辑 ~/.vimrc,Windows下编辑安装目录下的_vimrc
在前面加入一下代码:
set langmenu=zh_CN.UTF-8 "设置菜单语言
source
language messages zh_CN.utf-8 "设置提示信息语言
Android Studio 目录结构(http://ginsmile.github.io/blog/# 2015/05/23/how-to-import-opensource-project-and-solve-errors/#.VeSHPeEVi-u)
TestMe/build.gradle,全局gradle,在这个文件里的设置会在整个项目里通用。
TestMe/app/build.gradle,模块的gradle,仅在app模块通用。
TestMe/settings.gradle,用于指定哪个目录是模块model。里面的内容默认是include ':app',表示app这个文件夹是一个模块。
build.gradle文件第一行为:apply plugin: 'com.android.library',表示这是一个Library。
build.gradle文件第一行为:apply plugin: 'com.android.application',表示这是一个应用。
根目录下的setting.gradle里面是include ':MaterialDesign', ':MaterialDesignDemo'。表示以上两个文件夹都是module。
重命名Project
如何在Android Studio项目中导入开源库?
Android style中自定义属性
@color/colorPrimary
@color/colorPrimaryDark
@color/colorAccent
@color/window_background
@style/CardViewStyle.Light
@color/colorAccent
@android:color/black
@color/window_background
@color/state_selector_light
@color/progressBackgroundColorLight
@drawable/progress_drawable
@drawable/progress_drawable_withbackground
自定义的属性名是如何对应到相应的属性?
Android library projects cannot be launched 问题解决方法
eclipse DDMS always gives the error 'Can't bind to local 86XX for debugger' every time
方法: If you are using Linux, I recommend you as well to run this command:
fuser -k 8600/tcp
With this command you will kill any process running at the 8600 TCP port (The one Android is using to debug).
Error: Android开发~you need to use a theme.appcompat theme (or descendant) with this activity
AppCompatActivity cannot be resolved to a type?
No such property: nexusUsername for class: org.gradle.api.publication.maven.internal.ant.DefaultGroo
关机闹钟
系统闹钟有关机闹钟的功能
mobile log tools: ##84666364##
catch log information:
D/PowerOffAlarmManager( 876): LAUNCH_PWROFF_ALARM: android.intent.action.LAUNCH_POWEROFF_ALARM
D/PowerOffAlarmManager( 876): handleMessage enter msg name=ALARM_BOOT
D/PowerOffAlarmManager( 876): handleAlarmBoot
D/PowerOffAlarmManager( 876): maybeShowAlarmView start to showLocked
D/PowerOffAlarmManager( 876): handleMessage exit msg name=ALARM_BOOT
D/PowerOffAlarmManager( 876): sendRemoveIPOWinBroadcast ...
D/PowerOffAlarmManager( 876): NORMAL_BOOT_ACTION: android.intent.action.normal.boot
D/PowerOffAlarmManager( 876): handleMessage enter msg name=RESHOW_KEYGUARD_LOCK
D/PowerOffAlarmManager( 876): handleMessage exit msg name=RESHOW_KEYGUARD_LOCK
PowerOffAlarmManager.java
PowerOffAlarm.java
key log: D/AlarmManager( 747): set alarm to RTC 11932058
-------> AlarmManagerService--setLocked
Pinoy version
the version of Pinoy.apk should name after platform version and add date, e.g. 1.151015
when client feed back bugs about APP, first check the app version to ensure synchronization.
Android源码分析-Alarm机制与Binder的交互(http://blog.csdn.net/singwhatiwanna/article/details/18448997#)
3.1 什么是Alarm?
Alarm是android提供的用于完成闹钟式定时任务的类,系统通过AlarmManager来管理所有的Alarm,Alarm支持一次性定时任务和循环定时任务。
example:
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), TestActivity.class);
PendingIntent pendIntent = PendingIntent.getActivity(getApplicationContext(),
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//5秒后发送广播,只发送一次
int triggerAtTime = SystemClock.elapsedRealtime() + 5 * 1000;
alarmMgr.set(AlarmManager.RTC_WAKEUP, triggerAtTime, pendIntent);
3.2 Alarm和Timer以及Handler在定时任务上的区别
相同点:
三者都可以完成定时任务,都支持一次性定时和循环定时(注:Handler可以间接支持循环定时任务)
不同点:
Handler和Timer在定时上是类似的,二者在系统休眠的情况下无法正常工作,定时任务不会按时触发。Alarm在系统休眠的情况下可以正常工作,并且还可以决定是否唤醒系统,同时Alarm在自身不启动的情况下仍能正常收到定时任务提醒,但是当系统重启或者应用被杀死的情况下,Alarm定时任务会被取消。另外,从Android4.4开始,Alarm事件默认采用非精准方式,即定时任务可能会有小范围的提前或延后,当然我们可以强制采用精准方式,而在此之前,Alarm事件都是精准方式。
3.3 Alarm与Binder的交互
private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
PendingIntent operation, WorkSource workSource) {
if (triggerAtMillis < 0) {
/* NOTYET
if (mAlwaysExact) {
// Fatal error for KLP+ apps to use negative trigger times
throw new IllegalArgumentException("Invalid alarm trigger time "
+ triggerAtMillis);
}
*/
triggerAtMillis = 0;
}
try {
//定时任务实际上都有mService来完成,也就是说AlarmManager只是一个空壳
//从下面的构造方法可以看出,这个mService是IAlarmManager类型的,而IAlarmManager是一个接口
//如果大家了解AIDL就应该知道IAlarmManager应该是一个AIDL接口
mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation,
workSource);
} catch (RemoteException ex) {
}
}
AIDL(Android Interface Definition Language)
AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
选择AIDL的使用场合
官方文档特别提醒我们何时使用AIDL是必要的:只有你允许客户端从不同的应用程序为了进程间的通信而去访问你的service,以及想在你的service处理多线程。如果不需要进行不同应用程序间的并发通信(IPC),you should create your interface by implementing a Binder;或者你想进行IPC,但不需要处理多线程的,则implement your interface using a Messenger。无论如何,在使用AIDL前,必须要理解如何绑定service——bindService。如何绑定服务,请参考我的另一篇文章:http://blog.csdn.net/singwhatiwanna/article/details/9058143。
远程服务的创建和调用需要使用AIDL语言,一般分为以下几个过程
1.使用AIDL语言定义远程服务的接口
2.通过继承Service类实现远程服务
* IMathService.aidl是对远程服务接口的定义,自动生成的IMathService.java内部实现了远程服务数据传递的相关方法
* 实现远程服务需要建立一个继承android.app.Service的类,并在该类中通过onBind()方法返回IBinder对象,调用者使用返回的IBinder对象访问远程服务
IBinder对象的建立通过使用IMathService.java内部的Stub类实现,并逐一实现在IMathService.aidl接口文件定义的函数。
3.绑定和使用远程服务
在什么情况下使用 startService 或 bindService 或 同时使用startService 和 bindService
在 AndroidManifest.xml 里 Service 元素的常见选项
android:name ------------- 服务类名
android:label -------------- 服务的名字,如果此项不设置,那么默认显示的服务名则为类名
android:icon -------------- 服务的图标
android:permission ------- 申明此服务的权限,这意味着只有提供了该权限的应用才能控制或连接此服务
android:process ---------- 表示该服务是否运行在另外一个进程,如果设置了此项,那么将会在包名后面加上这段字符串表示另一进程的名字
android:enabled ---------- 如果此项设置为 true,那么 Service 将会默认被系统启动,不设置默认此项为 false
android:exported --------- 表示该服务是否能够被其他应用程序所控制或连接,不设置默认此项为 false
when Pinoy alarm is ringing, display "AUDIOFOCUS_LOSS_RANSIENT" after open the video interface.
Android基础概念Context的作用(http://bbs.csdn.net/topics/360043738)
如何解决Android 5.0中出现的警告:Service Intent must be explicit
Remote Service(RemoteMathCallerDemo) error:
API 21: Unable to start service Intent { act=edu.hrbeu.RemoteMathServiceDemo.MathService pkg=edu.hrbeu.RemoteMathCallerDemoActivity } U=0: not found
Service Intent must be explicit: Intent { act=edu.hrbeu.RemoteMathServiceDemo.MathService }
Android 5.0一出来后,其中有个特性就是Service Intent must be explitict. So change API from 21 to 19, the demo is work well. But how could we realize the remote service demo on API 21?
Pinoy->MyCountry->Alammoba->History: the item icon is wrong.
Parcelable对象
Looper(http://blog.csdn.net/thanksgining/article/details/43152555)
Looper通常是运行在一个消息的循环队列中的这个线程中,线程默认不会提供一个循环的消息去关联它们,即在一般的线程中是没有一个消息队列去关联这个消息的。那么如果线程想管理这些消息,就必须在此线程中调用Looper.prepare()使这个消息队列运行起来,并且调用Looper.loop()这个方法使它消息队列一直运行到停止。而Handler就是消息队列一个交互消息,包括从将消息发到消息队列,以及从消息队列取出消息并处理。
UI线程默认有个Looper对象,在Activity有一个默认的Looper的对象,来处理子线程中发送的消息。如果在一般的子线程中是不能创建handler对象的,因为自身没有带Looper对象,而主线程中是自带有这个对象的,从主线程拿出这个对象的;所以Andriod为了方便,不要开发者自己创建消息循环,所以提供了令外一个类HandlerThread。
Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一队列,终由Handler处理
Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等
MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取
Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper,针对接收Message消息线程
Thread:线程,负责调度整个消息循环,即消息循环的执行场所
HandlerThread(http://blog.csdn.net/alex0203/article/details/7671492)
HandlerThread继承Thread,当线程开启时,也就是它run方法运行起来后,线程同时创建了一个含有消息队列的Looper,并对外提供自己这个Looper对象的get方法,这就是它和普通Thread唯一不同的地方。
HandlerThread继承与Thread,所以本身就是一个线程。他类似于创建了一个含有Looper对象的线程类,而Looper可以用于创建Handler类,这样我们就不用自己实例化Looper对象,调用preare和Loop了,而是直接调用HandlerThread。与普通的Thread相比,就是多了Looper对象。
为什么要使用HandlerThread
1、开发中如果多次使用类似new Thread(){}.start(); 这种方式开启一个子线程,会创建多个匿名线程,使得程序运行越来越慢,而HandlerThread自带Looper使他可以通过消息来多次重复使用当前线程,节省开支
2、android系统提供的Handler类内部的Looper默认绑定的是UI线程的消息队列,对于非UI线程又想使得消息机制,那么HandlerThread内部的Looper是最合适的,它不会干扰或阻塞UI线程
用法:
1、HandlerThread继承Thread,与Thread不同就是提供自己的Looper对象,不过需要先启动这个HandlerThread线程
2、调用handlerThread.getLooper()来获取Looper对象,则不要调用Looper.prepare()和Looper.loop()方法
Android中的回调Callback(http://blog.csdn.net/shulianghan/article/details/16887509)
例如给安卓添加按钮点击事件, 我们创建了OnClickListener接口 实现了其中的onClick方法, 在合适的时机(按钮被点击的时候) , 就会执行我们实现的onClick()方法. 这个方法就被回调了 .
如何定义一个回调
a. 定义接口 : 在类中定义一个Interface, 并在接口中定义一个抽象方法;
b. 接口对象 : 在类中定义一个该接口的成员变量;
c. 设置对象 : 在类中定义一个公共的方法, 可以设置这个接口的对象, 调用该方法给接口对象成员变量赋值;
d. 调用方法 : 在合适的位置调用接口对象中的方法;
android LocalActivityManager
Helper class for managing multiple running embedded activities in the same process. This class is not normally used directly, but rather created for you as part of theActivityGroup implementation.
LocalActivityManager内部机制的核心在于,它使用了主线程对象mActivityThread来装载指定的Activity。注意,这里是装载,而不是启动.
LocalActivityManager类是管理activity的,然后通过startActivity(String id,Intent intent)这个方法获取Window获取当前Window对象,再然后调用getDecorView()方法获取当前activity对应的view.
在oncreate,onresume,onpause方法中分别加入如下代码:
oncreate()--------------mLocalActivityManager.dispatchCreate(savedInstanceState);
onpause()--------------mLocalActivityManager.dispatchPause(false);
onresume()--------------mLocalActivityManager.dispatchResume();
TabActivity,LocalActivityManager,TabHost,TabWidget深度分析(http://blog.csdn.net/fzh0803/article/details/6559081)
TabAcitivity继承自AcitivtyGroup,AcitivityGroup的主要作用是创建一个LocalActivityManger,然后把activity的onCreate等事件传递给LocalActivity来处理,作用仅此而已,非常简单。
TabActivity真正重要的包括三部分,TabHost,TabWidget,LocalActivityManager.
TabHost主要是面向用户的接口,它的主要作用就是添加tab,用TabSpec来完成一个完整的tab的抽象(包括标签及其内容),一个string 类型的tag,这个tag用来标识一个tab,比如在退出程序时记录当前是哪个tab以便在再次进入的时候显示退出前显示的tab,它最重要的作用在于当用intent做为一个tab,即要把一个activity作为内容(content)嵌入(即embeded activity的概念)进去,成为一个tab的内容。
TabActivity真正存在的原因就是为了embeded activity,即把activity做为一个view加入到另一个actvity中,而又有LocalActivityManger来控制activity的生命周期所以不必操心生命周期问题。
Android点九图(.9.png)的特点和制作
点九图又称九图,是一种png格式的图片,其后缀为.9.png ,其与传统png图片不同的地方是,点九图的四周边缘各有1个像素宽高的区域,而且只能填两种颜色,透明(#00000000)和黑色(#FF000000),其目的是用于对该图片的扩展区域和内容显示区域进行定义。
左侧和上侧作为扩展区域,右侧和下侧则是控制文字显示的区域。(左上拉伸区域)当需要上下拉伸的时候,就从左侧的黑色区域开始复制拉伸;当需要左右拉伸的时候,就从上侧的黑色区域开始拉伸。(右下文字显示区域)当想要在显示文字时,控制其与上下或左右边缘的距离,可以设置右侧或下侧的黑色区域,右侧的黑色区域控制文字上下位置,下侧控制文字的左右位置。
android xml文件名字命名
Android中的Handler, Looper, MessageQueue和Thread
Android 系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列和一个消息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环
职责
Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。
Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。
MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。
Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。
Thread:线程,负责调度整个消息循环,即消息循环的执行场所。
android:label
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="test1"
android:theme="@style/AppTheme" >
android:name=".MainActivity"
android:label="test2" >
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
test1: Displayed in App info
test2: Displayed in App name
"重载","复写"
区别 方法重载 方法复写
英文单词 Overloading Override
概念 方法名称相同,参数的个数或者类型不同 方法名称相同,参数的个数和类型相同,方法的访问权限不能更严格
使用范围 发生在同一个类中 发生在继承关系中,是由子类进行复写
判断手机是否有装载好的SDcard
Music->MusicUtils>hasMountedSDcard
static boolean hasMountedSDcard(Context context) {
StorageManager storageManager = (StorageManager) context.getSystemService(
Context.STORAGE_SERVICE);
boolean hasMountedSDcard = false;
if (storageManager != null) {
String[] volumePath = storageManager.getVolumePaths();
if (volumePath != null) {
String status = null;
int length = volumePath.length;
for (int i = 0; i < length; i++) {
status = storageManager.getVolumeState(volumePath[i]);
MusicLogUtils.d(TAG, "hasMountedSDcard: path = " + volumePath[i] + ",status = "
+ status);
if (Environment.MEDIA_MOUNTED.equals(status)) {
hasMountedSDcard = true;
}
}
}
}
MusicLogUtils.d(TAG, "hasMountedSDcard = " + hasMountedSDcard);
return hasMountedSDcard;
}
URI(Uniform Resource Identifier)
DCC就是通过了内部测试,符合公司正式发放流程。我们把最后一版测试叫DCC测试。客户那边确认软件后就不再给客户发软件了,只走内部测试流程,发现问题内部继续改。
Android中的Shape使用总结
*gradient:渐变
android:startColor和android:endColor分别为起始和结束颜色,
android:angle是渐变角度,必须为45的整数倍。
另外渐变默认的模式为android:type="linear",即线性渐变,
可以指定渐变为径向渐变,android:type="radial",径向渐变需要指定半径android:gradientRadius="50"。
*stroke:描边
android:width="2dp" 描边的宽度,android:color 描边的颜色。
我们还可以把描边弄成虚线的形式,设置方式为:
android:dashWidth="5dp"
android:dashGap="3dp"
其中android:dashWidth表示'-'这样一个横线的宽度,android:dashGap表示之间隔开的距离
*corners:圆角
android:radius为角的弧度,值越大角越圆。
我们还可以把四个角设定成不同的角度,
同时设置五个属性,则Radius属性无效
android:Radius="20dp" 设置四个角的半径
android:topLeftRadius="20dp" 设置左上角的半径
android:topRightRadius="20dp" 设置右上角的半径
android:bottomLeftRadius="20dp" 设置右下角的半径
android:bottomRightRadius="20dp" 设置左下角的半径
*padding:间隔
可以设置上下左右四个方向的间隔
查看git config信息
Pinoy多个相同闹钟问题:
当多个闹钟设置相同的闹铃时间或前一个闹钟响铃时后一个闹钟被启动时,因为前一个闹铃Activity A未被销毁,所以当关闭后一个闹钟Activity B之后,会跳转到Activity A,不符合设计要求。
原因(猜想):闹铃界面AlarmScreen运行在主线程,设置闹钟时间时,没有特意设定毫秒,所以闹钟时间的毫秒是系统“随机“设定(0-999)。当“同时”(间隔时间非常短,在几百毫秒之内,认为是同时)调用多个AlarmScreen时,会造成线程的阻塞。所以会造成某AlarmScreen没有启动,等前面的AlarmScreen被销毁后才被启动。
解决方案一:Activity B启动后,Activity A的将失去音频焦点,从而停止闹铃,finish()。但多个相同闹钟同时闹铃里,Activity却未被销毁???
解决方案二:将闹钟界面Activity的launchMode设为singleTop,这样就只会启动一个Activity。但如果是两个闹钟先后响起,即前一个闹钟还未响完,后一个闹钟也被启动,则后一个闹钟会失效。也不符合设计需求。
可行解决方案:设置闹钟时间时,设置时间间隔为100毫秒(或更长),这样启动AlarmScreen就有一个时间差,就不会造成主线程阻塞。
获取当前线程ID:Thread.currentThread().getId()
ActivityThread
resources: http://blog.csdn.net/ljsbuct/article/details/7094580
以前一直都说Activity的人口是onCreate方法。其实android上一个应用的入口,应该是ActivityThread。和普通的java类一样,入口是一个main方法。
写Pinoy总结,主要完成了大纲。
RemoteControlClient的使用(http://blog.csdn.net/liu149339750/article/details/31406701)
RemoteControlClient是从API 14也就是android 4.0开始出现的类,用于在锁屏状态控制音乐播放。界面是系统提供的。
api doc文档上附了一段注册代码
ComponentName myEventReceiver = new ComponentName(getPackageName(), MyRemoteControlEventReceiver.class.getName());
AudioManager myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
myAudioManager.registerMediaButtonEventReceiver(myEventReceiver);
// build the PendingIntent for the remote control client
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.setComponent(myEventReceiver);
PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
// create and register the remote control client
RemoteControlClient myRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
myAudioManager.registerRemoteControlClient(myRemoteControlClient);
1.1 RemoteViews(http://blog.csdn.net/tx16bing/article/details/41204287)
顾名思义,它是一个远程视图。App Widget中的视图,都是通过RemoteViews表现的。
在RemoteViews的构造函数中,通过传入layout文件的id来获取 “layout文件对应的视图(RemoteViews)”;然后,调用RemoteViews中的方法能对layout中的组件进行设置(例如,可以调用setTextViewText()来设置TextView组件的文本,可以调用setOnClickPendingIntent() 来设置Button的点击响应事件)。
因此,我们可以将 “RemoteViews 看作是 layout文件中所包含的全部视图的集合”。
1.2 RemoteViewsService
RemoteViewsService,是管理RemoteViews的服务。
一般,当App Widget 中包含“GridView、ListView、StackView等”集合视图时,才需要使用RemoteViewsService来进行更新、管理。(集合视图是指GridView、ListView、StackView等包含子元素的视图)
RemoteViewsService更新“集合视图”的一般步骤是:
(01) 通过setRemoteAdapter来设置 “RemoteViews对应RemoteViewsService”。
(02) 之后在RemoteViewsService中,实现RemoteViewsFactory接口。然后,在RemoteViewsFactory接口中对“集合视图”的各个子项进行设置(“集合视图”的各个子项:例如,GridView的每一个格子都是一个子项;ListView中的每一列也是一个子项)。
因此,我们可以将 “RemoteViewsService 看作是 管理layout中集合视图的服务”。
1.3 RemoteViewsFactory
通过RemoteViewsService中的介绍,我们可以了解“RemoteViewsService是通过RemoteViewsFactory来具体管理layout中集合视图的”,即“RemoteViewsFactory管理集合视图的实施者”。
RemoteViewsFactory是RemoteViewsService中的一个接口。RemoteViewsFactory提供了一系列的方法管理“集合视图”中的每一项。例如:
(01)RemoteViews getViewAt(int position)
通过getViewAt()来获取“集合视图”中的第position项的视图,视图是以RemoteViews的对象返回的。
(02)int getCount()
通过getCount()来获取“集合视图”中所有子项的总数。
因此,我们可以将 “RemoteViewsFactory 看作是 layout中集合视图管理的具体实施者”。
ActivityManager.isUserAMonkey:用来判断用户是不是在胡乱使用手机,像猴子一样。
修改提交log信息
git commit –amend 可以修改最后一次提交的信息。
对于历史提交,必须使用rebase。
git rebase –i HEAD~3
表示要修改当前版本的倒数第三次状态。执行这个命令后,会显示:
pick:
pick:
pick:*
如果你要修改哪个,就将那行的pick改成edit,然后退出。然后再使用:
git commit –amend来对commit进行修改。
修改完成之后,使用git rebase –continue。
Object: Java 中有一个比较特殊的类,就是 Object类,它是所有类的父类,如果一个类没
有使用 extends 关键字明确标识继承另外一个类,那么这个类就默认继承 Object 类。因此,Object 类是 Java类层中的最高层类,是所有类的超类。换句话说,Java 中任何一个类都是它的子类。由于所有的类都是由 Object 类衍生出来的,所以 Oject 类中的方法适用于所有类。
wait/notify 通常,多线程之间需要协调工作。例如,浏览器的一个显示图片的线程displayThread想要执行显示图片的任务,必须等待下载线程downloadThread将该图片下载完毕。如果图片还没有下载完,displayThread可以暂停,当downloadThread完成了任务后,再通知displayThread“图片准备完毕,可以显示了”,这时,displayThread继续执行。
以上逻辑简单的说就是:如果条件不满足,则等待。当条件满足时,等待该条件的线程将被唤醒。在Java中,这个机制的实现依赖于wait/notify。等待机制与锁机制是密切关联的。例如:
synchronized(obj) {
while(!condition) {
obj.wait();
}
obj.doSomething();
}
当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait()。在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:
synchronized(obj) {
condition = true;
obj.notify();
}
需要注意的概念是:
调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {…} 代码段内。
调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {…} 代码段内唤醒A。
当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。
如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。
obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。
当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。
可以用 instanceof 判断一个类是否实现了某个接口,也可以用它来判断一个实
例对象是否属于一个类。instanceof 的语法格式为:
对象 instanceof 类(或接口)
它的返回值是布尔型的,或真(true)、或假(false)。
mTextWidth = (int) tv.getPaint().measureText(tv.getText().toString());
- 学习Markdown。
- 学习Markdown画流程图。
- 写Pinoy项目总结。
- 第3章 音乐播放。
- 整理笔记,将dialy_review搬到Markdown
- 使用vim模式编辑Markdown文档
- 5030 Music源码。
W2JJW-4KYDP-2YMKW-FX36H-QYVD8
1 将markdown需要用的图片放到git仓库中,发布到github上
2 访问github仓库,https://github.com/guhuizaifeiyang/MarkdownPicture.git
3 访问图片
4 点击Raw按钮
5 拷贝链接地址https://github.com/guhuizaifeiyang/MarkdownPicture.git
6 在Markdown中引用图片
替換(substitute):[range]s/pattern/string/[c,e,g,i]5.1
range 指的是範圍,1,7 指從第一行至第七行,1,$ 指從第一行至最後一行,也就是整篇文章,也可以 % 代表。還記得嗎? % 是目前編輯的文章,# 是前一次編輯的文章。
pattern 就是要被替換掉的字串,可以用 regexp 來表示。
string 將 pattern 由 string 所取代。
c confirm,每次替換前會詢問。
e 不顯示 error。
g globe,不詢問,整行替換。
i ignore 不分大小寫。
示例:
:s/vivian/sky/ 替换当前行第一个 vivian 为 sky
:s/vivian/sky/g 替换当前行所有 vivian 为 sky
:n,$s/vivian/sky/ 替换第 n 行开始到最后一行中每一行的第一个 vivian 为 sky
:n,$s/vivian/sky/g 替换第 n 行开始到最后一行中每一行所有 vivian 为 sky
n 为数字,若 n 为 .,表示从当前行开始到最后一行
:%s/vivian/sky/(等同于 :g/vivian/s//sky/) 替换每一行的第一个 vivian 为 sky
:%s/vivian/sky/g(等同于 :g/vivian/s//sky/g) 替换每一行中所有 vivian 为 sky
可以使用 # 作为分隔符,此时中间出现的 / 不会作为分隔符
:s#vivian/#sky/# 替换当前行第一个 vivian/ 为 sky/
:s/vivian/sky/g 替换当前行所有 vivian 为 sky