Activity的复习以及在Onstart里设置网络连接

来源:互联网 发布:高仿椰子 知乎 编辑:程序博客网 时间:2024/06/05 12:03
安卓

目录(?)[-]

  1. 可视生命周期
  2. 前台声明周期
  3. 横竖屏切换
    1. 方式一
    2. 方式二
  4. onSaveInstanceState和onRestoreInstanceState

今天,首先对Activity的生命周期进行复习:

 (下面的截图部分是借鉴自赵雅智老师的博客。。。)

Activity的完整生命周期自第一次调用onCreate()开始,直至调用onDestroy()为止。ActivityonCreate()中设置所有“全局”状态以完成初始化,而在onDestroy()中释放所有系统资源。例如,如果Activity有一个线程在后台运行从网络下载数据,它会在onCreate()创建线程,而在 onDestroy()销毁线程。 

 

刚进入activity

 

按返回:

 

12显示完整的生命周期

 

 

可视生命周期

 

Activity的可视生命周期自onStart()调用开始直到相应的onStop()调用结束。在此期间,用户可以在屏幕上看到Activity,尽管它也许并不是位于前台或者也不与用户进行交互。在这两个方法之间,我们可以保留用来向用户显示这个Activity所需的资源。例如,当用户不再看见我们显示的内容时,我们可以在onStart()中注册一个BroadcastReceiver来监控会影响UI的变化,而在onStop()中来注消。onStart() 和 onStop() 方法可以随着应用程序是否为用户可见而被多次调用。 

 

按下home/第二个activity/黑屏在进入

 

再次进入:

 

 

完整的声明周期

 

前台声明周期

 

Activity的前台生命周期自onResume()调用起,至相应的onPause()调用为止。在此期间,Activity位于前台最上面并与用户进行交互。Activity会经常在暂停和恢复之间进行状态转换——例如当设备转入休眠状态或者有新的Activity启动时,将调用onPause() 方法。当Activity获得结果或者接收到新的Intent时会调用onResume() 方法。

当activityAndroidMenifest.xml文件中配置 

android:theme="@android:style/Theme.Dialog"

 

 

如果是普通的dialog 则不改变声明周期

横竖屏切换

默认情况下,当“屏幕方向”或“键盘显示隐藏” 变化时都会销毁当前Activity,创建新的Activity

 

 

如果不希望重新创建Activity实例,可以按如下配置Activity

方式一:

4.0以上配置

android:configChanges="orientation|screenSize|keyboardHidden"

4.0一下设置

android:configChanges="orientation|keyboardHidden"

方式二:

android:screenOrientation="landscape"

 

实际应用:在OnStart里设置网络连接:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.main;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.AlertDialog;  
  5. import android.content.DialogInterface;  
  6. import android.content.Intent;  
  7. import android.content.DialogInterface.OnClickListener;  
  8. import android.net.ConnectivityManager;  
  9. import android.net.NetworkInfo;  
  10. import android.os.Bundle;  
  11. import android.widget.Toast;  
  12.   
  13. public class MainActivity extends Activity {  
  14.   
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.activity_main);  
  19.     }  
  20.       
  21.     @Override  
  22.     protected void onStart() {  
  23.         super.onStart();  
  24.         checkNetWork();  
  25.     }  
  26.     public void checkNetWork() {  
  27.         //获取连接的管理对象  
  28.         ConnectivityManager connectivityManager= (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);  
  29.         //获取当前正在使用的网络  
  30.         NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();  
  31.         //判断网络是否可用  
  32.         if(networkInfo!=null&&networkInfo.isConnected()){  
  33.             if(networkInfo.getType()==ConnectivityManager.TYPE_MOBILE){  
  34.                 Toast.makeText(this,"...正在使用手机流量...", Toast.LENGTH_LONG).show();  
  35.             }else if(networkInfo.getType()==ConnectivityManager.TYPE_WIFI){  
  36.                 Toast.makeText(this"...正在使用无线网...", Toast.LENGTH_LONG).show();  
  37.             }  
  38.         }else{  
  39.             new AlertDialog.Builder(this)  
  40.                     .setTitle("请设置网络连接")  
  41.                     .setMessage("网络没有打开,请进行设置")  
  42.                     .setIcon(R.drawable.ic_launcher)  
  43.                     .setPositiveButton("确定"new OnClickListener() {  
  44.                 @Override  
  45.                 public void onClick(DialogInterface dialog, int which) {  
  46.                     Toast.makeText(MainActivity.this"确定", Toast.LENGTH_LONG).show();  
  47.                         }  
  48.                     }).setNegativeButton("去设置"new OnClickListener() {  
  49.                 @Override  
  50.                 public void onClick(DialogInterface dialog, int which) {  
  51.                     Toast.makeText(MainActivity.this"去设置", Toast.LENGTH_LONG).show();  
  52.                     Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);  
  53.                     startActivity(intent);  
  54.                 }  
  55.             }).create().show();  
  56.         }  
  57.     }  
  58. }  

onSaveInstanceState()和onRestoreInstanceState()

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState() 会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。

另外,当屏幕的方向发生了改变, Activity会被摧毁并且被重新创建,如果你想在Activity被摧毁前缓存一些数据,并且在Activity被重新创建后恢复缓存的数据。可以重写Activity的 onSaveInstanceState() 和 onRestoreInstanceState()方法,如下:

public class PreferencesActivity extends Activity {

    private String name;

    protected void onRestoreInstanceState(Bundle savedInstanceState) {

name = savedInstanceState.getString("name"); //被重新创建后恢复缓存的数据

super.onRestoreInstanceState(savedInstanceState);

    }

protected void onSaveInstanceState(Bundle outState) {

outState.putString("name", "liming");//被摧毁前缓存一些数据

super.onSaveInstanceState(outState);

    }

}


三、加载模式:

配置Activity时可指定android:launchMode属性,该属性用于配置该Activity的加载模式,其属性值有:
standard 标准模式,默认加载模式
singleTop Task顶单例模式
singleTask Task内单例模式
singleInstance 全局单例模式

 

Activity的加载模式,就负责管理实例化、加载Activity的方式、并可以控制Activity与Task之间的加载关系

 

Task:

ndroid采用Task来管理多个Activity,当我们启动一个应用时,android就会为之创建了一个Task,然后启动这个应用的入口(即<intent-filter.../>中配置MAIN和LAUNCHER的Activity)
android并没有为Task提供API,因此开发者无法真正访问Task,只能调用Activity的getTaskId()方法来获取它所在的Task的ID。

standard模式:

每次通过这种模式启动目标Activity时,Android总会为目标Activity创建一个新的实例,并将该实例Activity添加到当前Task栈中-这种模式不会启动新的Task,新Activity将被添加到原有的Task中,事实上我们可以把Task理解为Activity的栈,Task以栈的形式来管理Activity,先启动的Activity被放在Task栈底,后启动的Activity被放在Task栈顶。

singleTop模式:

与standard模式基本相似,但有一点不同,当将要被启动的目标Activity已经位于Task栈顶时,系统不会重新创建目标Activity实例,而是直接复用已有的Activity实例。

SingleTask模式:

采用这种加载模式的Activity在同一个Task内只有一个实例,当系统采用singleTask模式启动目标Activity时,有如下三种情况
如果将要启动的目标不存在,系统将会创建目标Activity的实例,并将它加入Task栈顶
如果将要启动的目标Activity已经位于Task栈顶,此时与singleTop模式行为相同
如果将要启动的目标Activity已经存在,但没有位于Task栈顶,系统将会把位于该Activity上面的所有Activity移出Task栈,从而使的目标Activity转入栈顶。

singleInstance模式:

这种加载模式下,系统保证无论从那个Task中启动目标Activity,只会创建一个目标Activity实例,并会使用一个全新的Task栈来装载该Activity实例。分为如下两种情况
如果将要启动的目标Activity不存在,系统会先创建一个全新的Task,再创建目标Activity实例,并将它加入新的Task栈顶
如果将要启动的目标Activity已经存在,无论它位于那个应用程序中,无论它位于那个Task中,系统将会把Activity所在的Task转到前台,从而使用该Activity显示出来.

四、内部存储数据的读取和回显:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.internalstorage;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.AlertDialog;  
  5. import android.content.Context;  
  6. import android.content.DialogInterface;  
  7. import android.content.DialogInterface.OnClickListener;  
  8. import android.os.Bundle;  
  9. import android.text.TextUtils;  
  10. import android.view.View;  
  11. import android.widget.CheckBox;  
  12. import android.widget.EditText;  
  13. import android.widget.Toast;  
  14.   
  15. public class MainActivity extends Activity {  
  16.   
  17.     private EditText et_name, et_pass;  
  18.     private CheckBox chbx_rem;  
  19.     private String fileName = "mima.txt";  
  20.     private InternalStorage internalStorage;  
  21.   
  22.     @Override  
  23.     protected void onCreate(Bundle savedInstanceState) {  
  24.         super.onCreate(savedInstanceState);  
  25.         setContentView(R.layout.activity_main);  
  26.         et_name = (EditText) findViewById(R.id.editusername);  
  27.         et_pass = (EditText) findViewById(R.id.editpass);  
  28.         // 记住密码的控件  
  29.         chbx_rem = (CheckBox) findViewById(R.id.checkbox);  
  30.         // 实例化存储对象  
  31.         internalStorage = new InternalStorage(MainActivity.this);  
  32.         // 通过存储对象得的方法来读取文件内容  
  33.         String values[] = internalStorage.readFile(fileName);  
  34.         if (values != null) {  
  35.             // 设置记住的用户名和密码  
  36.             et_name.setText(values[0]);  
  37.             et_pass.setText(values[1]);  
  38.         }  
  39.     }  
  40.   
  41.     public void login(View v) {  
  42.   
  43.         String username = et_name.getText().toString();  
  44.         String userpass = et_pass.getText().toString();  
  45.   
  46.         if (TextUtils.isEmpty(username) || TextUtils.isEmpty(userpass)) {  
  47.             Toast.makeText(this"用户名和密码不能为空 ", Toast.LENGTH_LONG).show();  
  48.         } else {  
  49.             //设置保存的用户名和密码的格式  
  50.             final String content = username + ";" + userpass;  
  51.             if (!chbx_rem.isChecked()) {  
  52.                 new AlertDialog.Builder(this).setMessage("请勾选记住密码,方便以后登录")  
  53.                         .setPositiveButton("否"new OnClickListener() {  
  54.                             @Override  
  55.                             public void onClick(DialogInterface dialog,  
  56.                                     int which) {  
  57.                             }  
  58.                         }).setNegativeButton("是"new OnClickListener() {  
  59.                             @Override  
  60.                             public void onClick(DialogInterface dialog,  
  61.                                     int which) {  
  62.                                 chbx_rem.setChecked(true);  
  63.                                 internalStorage.save(fileName, content, Context.MODE_PRIVATE);  
  64.                             }  
  65.                         }).create().show();  
  66.             } else {  
  67.                 // 直接操作  
  68.                 internalStorage.save(fileName, content, Context.MODE_PRIVATE);  
  69.                 Toast.makeText(this"文件已保存", Toast.LENGTH_LONG).show();  
  70.             }  
  71.         }  
  72.     }  
  73. }  


调用的save()和read方法:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.internalstorage;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileNotFoundException;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9.   
  10. import www.csdn.net.util.StreamTools;  
  11. import android.content.Context;  
  12.   
  13. public class InternalStorage {  
  14.   
  15.     private Context context;  
  16.   
  17.     public InternalStorage(Context context) {  
  18.         this.context = context;  
  19.     }  
  20.   
  21.     /* 
  22.      * 文件保存 文件名称,文件内容,文件保存的模式 
  23.      */  
  24.     public void save(String fileName, String content, int mode) {  
  25.         try {  
  26.             FileOutputStream fos = context.openFileOutput(fileName, mode);  
  27.             fos.write(content.getBytes());  
  28.             // 立即写入  
  29.             fos.flush();  
  30.             // 关闭  
  31.             fos.close();  
  32.   
  33.         } catch (IOException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.     }  
  37.   
  38.     // 根据文件的名称去读取文件的内容  
  39.     public String[] readFile(String fileName) {  
  40.         String values[] = null;  
  41.         // 创建一个文件属性  
  42.         File file = new File(context.getFilesDir(), fileName);    
  43.         // 判断文件存在不存在  
  44.         if (file.exists()) {  
  45.             // 在这里操作  
  46.             try {  
  47.                 // 根据文件创建出文件的输入流  
  48.                 InputStream is = new FileInputStream(file);  
  49.                 // 文件存在,通过工具类读取文件内容  
  50.                 String value = StreamTools.streamToStr(is);  
  51.                 // 按照;进行拆分,返回数组对象  
  52.                 values = value.split(";");  
  53.   
  54.             } catch (FileNotFoundException e) {  
  55.                 e.printStackTrace();  
  56.             }  
  57.         }  
  58.         // 记得申明返回对象  
  59.         return values;  
  60.     }  
  61. }  

 五、将数据文件存储在SD卡上的操作,保存成私密文件。读取也是私密文件:

1、ManAcvitity主文件:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.externalstorage;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5. import java.io.IOException;  
  6.   
  7. import com.example.service.FileService;  
  8.   
  9. import android.app.Activity;  
  10. import android.os.Bundle;  
  11. import android.os.Environment;  
  12. import android.view.View;  
  13. import android.widget.CheckBox;  
  14. import android.widget.EditText;  
  15. import android.widget.Toast;  
  16.   
  17. public class MainActivity extends Activity {  
  18.   
  19.     private EditText et_name, et_pass;  
  20.     private CheckBox chbx_rem;  
  21.   
  22.     private String fileName = "csdn1.txt";  
  23.   
  24.     private FileService fileService;  
  25.   
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.activity_main);  
  30.   
  31.         // 获取控件对象  
  32.         et_name = (EditText) findViewById(R.id.et_name);  
  33.         et_pass = (EditText) findViewById(R.id.et_pass);  
  34.         chbx_rem = (CheckBox) findViewById(R.id.chbx_rem);  
  35.   
  36.         // 创建业务对象  
  37.         fileService = new FileService();  
  38.         // 获取sdcard上读取到的文件内容  
  39.         String values[] = fileService.readFile(this, Environment.DIRECTORY_DOWNLOADS, fileName);  
  40.         if (values != null) {  
  41.             // 设置用户名  
  42.             et_name.setText(values[0]);  
  43.             // 设置用户密码  
  44.             et_pass.setText(values[1]);  
  45.         }  
  46.     }  
  47.   
  48.     /** 
  49.      * 检测你的外部存储设备是否安装,并且是否可读和可写 
  50.      *  
  51.      * @return 
  52.      */  
  53.     public boolean isExternalStorageAvailable() {  
  54.         // 声明返回的变量  
  55.         boolean flag = false;  
  56.         // 获取设备的状态  
  57.         String state = Environment.getExternalStorageState();  
  58.         // 判断设备是否安装,并且是否可读和可写  
  59.         if (Environment.MEDIA_MOUNTED.equals(state)) {  
  60.             // 返回真  
  61.             flag = true;  
  62.         }  
  63.         // 记得修改返回变量  
  64.         return flag;  
  65.     }  
  66.   
  67.     public void login(View v) {  
  68.         String userName = et_name.getText().toString();  
  69.         String userPass = et_pass.getText().toString();  
  70.   
  71.         String content = userName + ";" + userPass;  
  72.   
  73.         if (chbx_rem.isChecked()) {  
  74.             // 如果要操作外部存储设备,1.需要添加权限。 2.需要判断有没有外部存储设备  
  75.   
  76.             // 判断你的外部设备是否安装,是否可读可写  
  77.             if (isExternalStorageAvailable()) {  
  78.                 // 公共文件  
  79.                 fileService.saveFile(this,fileName, content,Environment.DIRECTORY_DOWNLOADS);  
  80.                 // 私密文件  
  81.                 Toast.makeText(this"文件保存成功.", Toast.LENGTH_LONG).show();  
  82.   
  83.             } else {  
  84.                 Toast.makeText(this"请检查你的外部设备的操作", Toast.LENGTH_LONG).show();  
  85.             }  
  86.   
  87.         } else {  
  88.   
  89.         }  
  90.     }  
  91. }  


2.FileService(具体方法实现类):

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.service;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileNotFoundException;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9.   
  10. import android.content.Context;  
  11. import android.os.Environment;  
  12.   
  13. import com.example.util.StreamTools;  
  14.   
  15. public class FileService {  
  16.   
  17.     /** 
  18.      * 文件存储到SDCard上的操作(公共文件) 
  19.      *  
  20.      * @param fileName 
  21.      *            :文件名称 
  22.      * @param content 
  23.      *            :文件内容 
  24.      * @param dir 
  25.      *            :文件存储到SDCard的目录文件 
  26.      */  
  27.     public void saveFile(String fileName, String content, String dir) {  
  28.         // 演示公共文件  
  29.         File sdCardDir = Environment.getExternalStoragePublicDirectory(dir);  
  30.         //Environment.getExternalStorageDirectory()  
  31.         // 创建文件对象  
  32.         File file = new File(sdCardDir, fileName);  
  33.   
  34.         try {  
  35.             // 创建文件输出流对象  
  36.             FileOutputStream fos = new FileOutputStream(file);  
  37.             // 通过文件输出流对象写入  
  38.             fos.write(content.getBytes());  
  39.             // 立即写入  
  40.             fos.flush();  
  41.             // 关闭  
  42.             fos.close();  
  43.         } catch (IOException e) {  
  44.             // TODO Auto-generated catch block  
  45.             e.printStackTrace();  
  46.         }  
  47.     }  
  48.   
  49.     /** 
  50.      * 读取文件(公共文件) 
  51.      *  
  52.      * @param dir 
  53.      *            :sdcard的目录 
  54.      * @param fileName 
  55.      *            :文件的名称 
  56.      * @return:返回的是用户名和密码 
  57.      */  
  58.     public String[] readFile(String dir, String fileName) {  
  59.         // 声明返回值  
  60.         String values[] = null;  
  61.         // 根据sdcard的目录创建文件对象  
  62.         File file = new File(  
  63.                 Environment.getExternalStoragePublicDirectory(dir), fileName);  
  64.   
  65.         // 判断文件是否存在  
  66.         if (file.exists()) {  
  67.             try {  
  68.                 // 根据文件,创建文件输出流对象的时候有一个文件找不到的异常  
  69.                 InputStream is = new FileInputStream(file);  
  70.                 // 利用工具类处理  
  71.                 String value = StreamTools.streamToStr(is);  
  72.                 values = value.split(";");  
  73.             } catch (FileNotFoundException e) {  
  74.                 // TODO Auto-generated catch block  
  75.                 e.printStackTrace();  
  76.             }  
  77.         }  
  78.         // 记得修改返回值  
  79.         return values;  
  80.     }  
  81.   
  82.     /** 
  83.      * 保存文件(私密文件) 
  84.      *  
  85.      * @param context 
  86.      *            :上下文件对象 
  87.      * @param fileName 
  88.      *            :文件名称 
  89.      * @param content 
  90.      *            :文件内容 
  91.      * @param dir 
  92.      *            :文件sdcard的目录 
  93.      */  
  94.     public void saveFile(Context context, String fileName, String content,  
  95.             String dir) {  
  96.         // 演示公共文件  
  97.         File sdCardDir = context.getExternalFilesDir(dir);  
  98.           
  99.         // 创建文件对象  
  100.         File file = new File(sdCardDir, fileName);  
  101.         System.out.println("---------------------------"+file.getPath()+"--------------------");  
  102.   
  103.         try {  
  104.             // 创建文件输出流对象  
  105.             FileOutputStream fos = new FileOutputStream(file);  
  106.             // 通过文件输出流对象写入  
  107.             fos.write(content.getBytes());  
  108.             // 立即写入  
  109.             fos.flush();  
  110.             // 关闭  
  111.             fos.close();  
  112.         } catch (IOException e) {  
  113.             e.printStackTrace();  
  114.         }  
  115.           
  116.         System.out.println("=================================================================");  
  117.     }  
  118.   
  119.     /** 
  120.      * 读取文件(私密文件) 
  121.      *  
  122.      * @param context 
  123.      *            :上下文对象 
  124.      * @param dir 
  125.      *            :文件目录 
  126.      * @param fileName 
  127.      *            :文件名称 
  128.      * @return:读取到的用户名和密码 
  129.      */  
  130.     public String[] readFile(Context context, String dir, String fileName) {  
  131.         // 声明返回值  
  132.         String values[] = null;  
  133.         // 根据sdcard的目录创建文件对象  
  134.         File file = new File(context.getExternalFilesDir(dir), fileName);  
  135.   
  136.         // 判断文件是否存在  
  137.         if (file.exists()) {  
  138.             try {  
  139.                 // 根据文件,创建文件输出流对象的时候有一个文件找不到的异常  
  140.                 InputStream is = new FileInputStream(file);  
  141.                 // 利用工具类处理  
  142.                 String value = StreamTools.streamToStr(is);  
  143.                 values = value.split(";");  
  144.             } catch (FileNotFoundException e) {  
  145.                 // TODO Auto-generated catch block  
  146.                 e.printStackTrace();  
  147.             }  
  148.         }  
  149.         // 记得修改返回值  
  150.         return values;  
  151.     }  
  152. }  

3、StreamTools(将字节流转换为字符流的工具类):

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.util;  
  2.   
  3. import java.io.ByteArrayOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6.   
  7. public class StreamTools {  
  8.   
  9.     public static String streamToStr(InputStream is) {  
  10.         try {  
  11.             // 字节数组输出流对象  
  12.             ByteArrayOutputStream os = new ByteArrayOutputStream();  
  13.             // 读取长度  
  14.             int len = 0;  
  15.             // 读取的缓冲区  
  16.             byte buffer[] = new byte[1024];  
  17.             // 输入流循环读取 直到结尾  
  18.             while ((len = is.read(buffer)) != -1) {  
  19.                 // 读取的内容写入到字节数组输出流对象中  
  20.                 os.write(buffer, 0, len);  
  21.             }  
  22.             // 关闭流  
  23.             is.close();  
  24.             os.close();  
  25.             // 把字节数组输出流对象 转换成字节数组  
  26.             byte data[] = os.toByteArray();  
  27.             // 通过String构造函数把字节数组转换成字符串 并返回  
  28.             return new String(data);  
  29.   
  30.         } catch (IOException e) {  
  31.             e.printStackTrace();  
  32.             return null;  
  33.         }  
  34.     } 
0 0
原创粉丝点击