1、学习网址
http://hukai.me/android-training-course-in-chinese/basics/firstapp/building-ui.html
2、intent中定义变量的习惯方法:
public final static String EXTRA_MESSAGE = "com.mycompany.myfirstapp.MESSAGE";
定义key为一个public型的常量,通常使用应用程序包名作为前缀来定义键是很好的做法,这样在应用程序与其他应用程序进行交互时仍可以确保键是唯一的。
3、Android适配不同的语言的方式
(1)建立不同的values;其中中文:values_zh_CN,英文默认values,西班牙语,/values-es/strings.xml
:
(2)读取语言的方式默认是根据系统配置的语言进行读取的,
-
Resources resources = getResources(); // 获得res资源对象
-
Configuration config = resources.getConfiguration(); // 获得设置对象
-
DisplayMetrics dm = resources.getDisplayMetrics(); // 获得屏幕参数:主要是分辨率,像素等。
-
config.locale = Locale.ENGLISH</span>; // 设置APP语言设置为英文
-
resources.updateConfiguration(config, dm);
4、Android屏幕适配和宽横屏的方法
(1)横竖屏:建立不同的layout文件夹,横屏:layout-land,默认layout为竖屏
(2)不同分辨率:可以根据分辨率大小进行分别创建layout:小(small),普通(normal),大(large),超大(xlarge)
(3)图片使用不同大小:
- xhdpi: 2.0
- hdpi: 1.5
- mdpi: 1.0 (基准)
- ldpi: 0.75
这意味着,如果针对xhdpi的设备生成了一张200x200的图像,那么应该为hdpi生成150x150,为mdpi生成100x100, 和为ldpi生成75x75的图片资源。
5、Fragment的使用
(1)可以直接通过创建类继承Fragment,然后在activity的xml中直接引用fragment:
<fragment android:name="com.example.android.fragments.HeadlinesFragment"
android:id="@+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
(2)上面的这种方式一般用的比较少,可以直接在主Activity中,直接加载想要的Fragment
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// 将 fragment_container View 中的内容替换为此 Fragment,
// 然后将该事务添加到返回堆栈,以便用户可以向后导航
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// 执行事务
transaction.commit();
(3)Fragment如何和Activity进行通讯呢?
通过在activity中定义接口的方式,在fragment中直接调用activity的接口则可以进行值的传递。
6、APP可以被分享功能实现
通过在manifest文件中的<activity>
标签下添加<intent-filter>
的属性,使其他的app能够启动我们的activity。
<activity android:name="ShareActivity">
<!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
<intent-filter>
<action android:name="android.intent.action.SENDTO"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="sms" />
<data android:scheme="smsto" />
</intent-filter>
<!-- filter for sending text or images; accepts SEND action and text or image data -->
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/*"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
7、图片拍照后保存和将图片显示在相册中的方法
String mCurrentPhotoPath;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
(2)将图片保存到相册中的方法
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
(3)对图片进行压缩的方法
private void setPic() {
// Get the dimensions of the View
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
mImageView.setImageBitmap(bitmap);
}
8、创建后台服务IntentService
但是IntentService有下面几个局限性:
- 不可以直接和UI做交互。为了把他执行的结果体现在UI上,需要把结果返回给Activity。
- 工作任务队列是顺序执行的,如果一个任务正在IntentService中执行,此时你再发送一个新的任务请求,这个新的任务会一直等待直到前面一个任务执行完毕才开始执行。
- 正在执行的任务无法打断。
public class RSSPullService extends IntentService {
@Override
protected void onHandleIntent(Intent workIntent) {
// Gets data from the incoming Intent
String dataString = workIntent.getDataString();
...
// Do work here, based on the contents of dataString
...
}
}
<application
android:icon="@drawable/icon"
android:label="@string/app_name">
...
<!--
Because android:exported is set to "false",
the service is only available to this app.
-->
<service
android:name=".RSSPullService"
android:exported="false"/>
...
<application/>
如何回传IntentService中执行的任务状态与结果给发送方。 例如,回传任务的执行状态给Activity并进行更新UI。推荐的方式是使用LocalBroadcastManager,这个组件可以限制broadcast intent只在自己的app中进行传递。
9、Android页面布局的性能优化
1、Android SDK 工具箱中有一个叫做 Hierarchy Viewer 的工具,能够在程序运行时分析 Layout。你可以用这个工具找到 Layout 的性能瓶颈。
2、使用嵌套的 LinearLayout 可能会使得 View 的层级结构过深,此外,嵌套使用了 layout_weight
参数的 LinearLayout 的计算量会尤其大,因为每个子元素都需要被测量两次。这对需要多次重复 inflate 的 Layout 尤其需要注意,比如嵌套在 ListView 或 GridView 时。
3、没用的子节点 — 一个没有子节点或者背景的 Layout 应该被去掉,来获得更扁平的层级。
4、没用的父节点 — 一个节点如果没有兄弟节点,并且它不是 ScrollView
或根节点,没有背景,这样的节点应该直接被子节点取代,来获得更扁平的层级
5、太深的 Layout — Layout 的嵌套层数太深对性能有很大影响。尝试使用更扁平的 Layout ,比如 RelativeLayout
或 GridLayout
来提高性能。一般最多不超过10层。
6、合并根 frame — 如果 FrameLayout
是 Layout 的根节点,并且没有使用 padding 或者背景等,那么用 merge 标签替代他们会稍微高效些。