我的Android官方Training笔记-第一章

Android官方文档笔记

Getting Start

1. Supporting Different Devices

兼容不同的设备

  1. 适配不同区域语言.

———- 添加不同区域语言的字符串值到相应的文件.

英语(默认区域语言),/values/strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="title">My Application</string>
   <string name="hello_world">Hello World!</string>
</resources>

中文,/values-zh/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="title">我的应用程序</string>
   <string name="hello_world">大家好!</string>
</resources>

2.动态引用字符资源.

—–getResources方法

String hello = getResources().getString(R.string.hello_world);

—–setText方法

TextView textView = new TextView(this);
textView.setText(R.string.hello_world);

3.适配不同的屏幕

—–res/layout目录添加目录和同名的xml文件

MyProject/
res/
    layout/   /*默认适配  
        main.xml
    layout-large/  /*大屏幕适配
        main.xml
    layout-land/   /*横屏适配
        main.xml  

4.创建不同的Bitmap以适应不同的精度

  • xhdpi: 2.0
  • hdpi: 1.5
  • mdpi: 1.0 (基准)
  • ldpi: 0.75

——–将图片文件放入相应的drawable资源目录中:

Note:任何时候,当引用@drawable/awesomeimage时系统会根据屏幕的分辨率选择恰当的bitmap。

MyProject/
res/
    drawable-xhdpi/
        image.png
    drawable-hdpi/
        image.png
    drawable-mdpi/
        image.png
    drawable-ldpi/
        image.png

Note:低密度(ldpi)资源是非必要的,当提供了hdpi的图像,系统会把hdpi的图像按比例缩小一半,去适配ldpi的屏幕。


2. Activity的生命周期

onPause方法可做以下事情

  1. 停止动画或者是其他正在运行的操作,那些都会导致CPU的浪费.

  2. 提交在用户离开时期待保存的内容(例如邮件草稿).

  3. 释放系统资源,例如broadcast receivers, sensors (比如GPS), 或者是其他任何会影响到电量的资源。

Note:如果activity实际上是要被Stop,那么我们应该为了切换的顺畅而减少在OnPause()方法里面的工作量。

onResume

  • 应该实现onResume()来初始化那些在onPause方法里面释放掉的组件,并执行那些activity每次进入Resumed state都需要的初始化动作 (例如开始动画与初始化那些只有在获取用户焦点时才需要的组件)

onStop

  • 我们应该使用onStop()来执行那些CPU intensive的shut-down操作,例如往数据库写信息。我们需要使用onStop()来释放资源,从而避免内存泄漏。
恢复数据

☆☆☆ 通过重写onSaveInstanceState方法来保存Activity被意外终止的信息

public void onSaveInstanceState(Bundle savedInstanceState) {
// 保存用户之前使用的一些数据
savedInstanceState.putInt(STATE_SCORE, mCurrent);
//保存用户之前的视图信息
super.onSaveInstanceState(savedInstanceState);
}

☆☆☆ 通过重写onCreate方法来恢复Activity被意外终止的信息

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); 
// 优先申明这个子类
if (savedInstanceState != null) {
    mCurrent = savedInstanceState.getInt(STATE_SCORE);
} else {
  }
}

☆☆☆ 我们也可以选择实现 onRestoreInstanceState()方法恢复数据。
public void onRestoreInstanceState(Bundle savedInstanceState) {
// 通常通过调用此类来恢复视图信息
super.onRestoreInstanceState(savedInstanceState);
mCurrent = savedInstanceState.getInt(STATE_SCORE);
}

-onRestoreInstanceState()方法会在 onStart() 方法之后执行. 系统仅仅会在存在需要恢复的状态信息时才会调用 onRestoreInstanceState() ,不需要检查 Bundle 是否为null。


3. Buiding a Dynamic UI with Fragments

使用Fragment构建一个可交互UI界面

——项目源码:FragmentBasic

  1. 创建fragment模块类

    public class ArticleFragment extends Fragment {     
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
     Bundle savedInstanceState) {
     // 为碎片填充视图
     return inflater.inflate(R.layout.article_view, container, false);
     }
    }
    
  2. 静态添加fragment碎片(XML)

    <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" />
    
  3. 或动态添加fragment碎片

———- 创建一个布局容器:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/fragment_container"
 android:layout_width="match_parent"

———- 往容器中添加视图

  //当容器内容不为空时,不执行后面的语句。
  if (findViewById(R.id.fragment_container) != null) {
   if (savedInstanceState != null) {
   return;
  }

  HeadlinesFragment firstFragment = new HeadlinesFragment();
  //用来获取fragment的Intent额外信息
  firstFragment.setArguments(getIntent().getExtras());
  //开启事务添加碎片并提交
  getSupportFragmentManager().beginTransaction()
  .add(R.id.fragment_container, firstFragment).commit();

4.HeadLineFragment类继承ListFragment后直接setListAdapter即可显示列表

 setListAdapter(new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1,String));

5.☆覆写列表的点击事件,提供接口让父Activity实现

ArticleSelected articalFragment
......
public void onListItemClick(ListView l, View v, int position, long id){
  articalFragment.articleSelected(position);            
 }  
public  interface ArticleSelected{
    public void articleSelected(int poisition); 
}

6.☆父Activity实现接口并setArgument.MainActivity

    public void articleSelected(int poisition) {

    ArticalFragment articalFragment = new ArticalFragment();    
    Bundle bundle = new Bundle();
    bundle.putInt(ArticalFragment.KEY, poisition);
    articalFragment.setArguments(bundle);
    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();   
    fragmentTransaction.replace(R.id.container, articalFragment);
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();
}

7.☆在onAttach中回调接口

 public void onAttach(Context context) {
     super.onAttach(context);
     try {
           articalFragment = (ArticleSelected) context;
          } catch (ClassCastException e) {
             throw new ClassCastException(context.toString()
                     + " must implement OnHeadlineSelectedListener");
            }

8.Articlefragment类在onStart中获取传来的信息

public void onStart(){
super.onStart();
Bundle bundle = getArguments();
if(bundle != null){
 setTextView(bundle.getInt(KEY));
}
 public void updateArticleView(int position) {
    TextView article = (TextView) getActivity().findViewById(R.id.article);
    article.setText(Ipsum.Articles[position]);
  }
 }

4.Save Data

数据保存

1.SharedPreference保存

———- 获取SharedPreference

  • getSharedPreferences() — 需要多个名称参数来区分shared preference文件, 名称可以通过第一个参数来指定。可在app中通过任何一个Context 执行该方法

    Context context = getActivity();
    SharedPreferences sharedPref =  context.getSharedPreferences(
    getString(R.string.preference_file_key), Context.MODE_PRIVATE);
    
  • getPreferences() — 当activity仅需要一个shared preference文件时。
    SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);

———- 写Shared Preference

  • 通过执行edit()创建一个 SharedPreferences.Editor。

    SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit ();
    editor.putInt(getString (R.string.saved_high_score),   newHighScore);
    editor.commit();
    

———- 读Shared Preference

  • 提供一个默认的value作为查找的key不存在时函数的返回值。

    SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
    int defaultValue = getResources().getInteger (R.string.saved_high_score_default);
    long highScore = sharedPref.getInt(getString(R.string.saved_high_score), default);
    

2.保存文件

  • Internal storage(内部储存):

1.总是可用的

2.这里的文件默认只能被我们的app所访问。

3.当用户卸载app的时候,系统会把internal内该app相关的文件都清除干净。

4.Internal是我们在想确保不被用户与其他app所访问的最佳存储区域。

  • External storage(外部储存):

1.并不总是可用的,因为用户有时会通过USB存储模式挂载外部存储器,当取下挂载的这部分后,就无法对其进行访问了。

2.是大家都可以访问的,因此保存在这里的文件可能被其他程序访问。

3.当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。

4.External是在不需要严格的访问权限并且希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。

保存内部储存

① 使用File()构造器在目录下创建一个新的文件

File file = new File(context.getFilesDir(), filename);

openFileOutput()获取一个FileOutputStream用于写文件到internal目录(可设置不可读写)

String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;

try {
   outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
   outputStream.write(string.getBytes());
   outputStream.close();
} catch (Exception e) {
   e.printStackTrace();
}

③使用createTempFile()缓存文件

———- 缓存目录下的文件一旦不再需要马上被删除

public File getTempFile(Context context, String url) {
File file;
try {
    String fileName = Uri.parse(url).getLastPathSegment();
    file = File.createTempFile(fileName, null, context.getCacheDir());
catch (IOException e) {
    // Error while creating file
}
return file;

}

保存外部储存

  • 申明权限(只读)

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

Note:对于内存卡,不需要声明任何权限,默认有读写程序目录下文件的权限

  • 保存文件到外部卡

———- 判断外部卡是否可用。若返回状态为MEDIA_MOUNTED, 则可以读写

    /* 检查外部储存卡是否可读可写 */
    public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState  ();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
     return true;
    }
    return false;
    }

    /* 检查外部储存卡是否至少可读*/
    public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState    ();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
      Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
       return true;
     }
     return false;
    }

尽管外部储存卡对于用户与其他app是可修改的,我们可能会保存下面两种类型的文件。

  • Public files :用户卸载我们的app时,这些文件应该保留。例如,被我们的app拍摄的图片或者下载的文件。

    public File getAlbumStorageDir(String albumName) {
    // 需要带有一个特定的参数来指定这些public的文件类型.
    File file = new File (Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
    Log.e(LOG_TAG, "Directory not created");
    }
    return file;
    }
    
  • Private files: 在app被卸载时删除。

    如果刚开始的时候,没有预定义的子目录存放我们的文件,可以在 getExternalFilesDir()方法中传递null. 它会返回app在external storage下的private的根目录。

    public File getAlbumStorageDir(Context context, String albumName) {
    File file = new File(context.getExternalFilesDir(
            Environment.DIRECTORY_PICTURES), albumName);
     if (!file.mkdirs()) {
     Log.e(LOG_TAG, "Directory not created");
     }
     return file;
    }
    

删除文件

myFile.delete();

如果文件是保存在internal storage,我们可以通过Context来访问并通过执行deleteFile()进行删除

myContext.deleteFile(fileName);

3.保存到SQLite数据库

建立数据库结构

创建数据库

导入数据

数据库操作

5.Interacting with oher apps.

与其它App交互

  • 隐式Intent(查看网页)

     Uri webpage  = Uri.parse("http://www.android.com");
     Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage );
     //创建选择程序界面
    Intent Chooser = Intent.createChooser(webIntent,"选择界面标题");
    // 判断是否有程序接收此Intent
     PackageManager packageManager = getPackageManager();
     List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
     boolean isIntentSafe = activities.size() > 0;
    if(isIntentSafe){
    startActivity(chooser);
      }
    
  • 接收Activity返回的结果(读取联系人信息)

发送

static final int PICK_CONTACT_REQUEST = 1;  
...
private void pickContact() {
Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}

接收

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
       if (requestCode == PICK_CONTACT_REQUEST) {         
         if (resultCode == RESULT_OK) {

         Uri contactUri = data.getData();          
         String[] projection = {Phone.NUMBER};           
         Cursor cursor = getContentResolver()
                .query(contactUri, projection, null, null, null);
                cursor.moveToFirst();

        int column = cursor.getColumnIndex(Phone.NUMBER);
        String number = cursor.getString(column);          
       }
     }
    }
  • Intent过滤

静态添加Intent-Filter

<activity android:name="ShareActivity">
<intent-filter>
    <action android:name="android.intent.action.SEND"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="text/plain"/>
    <data android:mimeType="image/*"/>
</intent-filter>
</activity>

处理Intent

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);


Intent intent = getIntent();
Uri data = intent.getData();
//处理图片信息
if (intent.getType().indexOf("image/") != -1) {
  //处理文字信息
} else if (intent.getType().equals("text/plain")) {

 }
}   

返回Result

Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
setResult(Activity.RESULT_OK, result);
finish();

简单的只需要返回int值

setResult(RESULT_COLOR_RED);
finish();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值