11月8日Android学习笔记

标签

Android

Activity

图片

启动模式

intent

Bitmap

发布时间:

本文字数:1,905 字 阅读完需:约 4 分钟

框架的导入

在当前项目的build.gradledependencies中加入框架即可,如下例所示

build.gradle

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    implementation 'com.squareup.picasso:picasso:2.5.2' //导入的框架
}

加载网络图片

  1. 导入picasso框架 implementation 'com.squareup.picasso:picasso:2.5.2'

  2. 设置网络权限
    AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET"/>,申请网络权限 如下例:

     <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools">
     <uses-permission android:name="android.permission.INTERNET"/>
     .........
    
  3. 加载图片

        Picasso.with(context).load(bean.getPic()).into(holder.iv);

tips

listview当中包含button类型,需要在item布局外层添加这个属性,避免被抢占焦点

android:descendantFocusability="blocksDescendants"

如下例

item_detailgv.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:descendantFocusability="blocksDescendants"
    android:padding="10dp">

启动模式

支持四种属性值:

  1. standard :标准模式,默认的启动模式。
  2. singleTop : 栈顶单例模式
  3. singleTask : 栈内单例模式
  4. singleInstance:全局单例模式

为什么activity会有加载模式呢?加载模式有什么用呢?
activity的加载模式,就是负责管理实例化,加载activity的方式,并可以控制activity和task之间的加载关系。

【standard模式】

标准启动模式,当启动目标activity的时候都会创建一个新的实例,并且将当前的activity放在栈顶。 这个模式不会启动新的task。新的activity会被添加到原来的task当中。

【singleTop模式】

在栈顶就重用,否则就用新的。
当需要启动的目标activity已经位于栈顶的时候,系统就不会创建新的目标activity的实例,而是直接复用已有的 activity的实例。
原理:主要是因为他调用了activity类的onNewIntent()方法,可以在该方法当中刷新页面数据。

举例:短信编辑页面

【singleTask模式】

采用这个模式的activity在task栈内只有一个实例,当系统使用这个模式启动目标activity时,可以分为三种情况。
(1).如果将要启动的目标activity不存在,系统将会创建目标activity的实例,并且将他放到task栈顶。
(2).如果将要启动的目标activity已经位于task栈顶,此时就和singleTop的模式的行为是相同的。
(3).如果将要启动的目标activity已经存在,但是没有位于task栈顶,系统将会把位于该activity上面的所有
activity都移出task栈,从而是的目标activity就转入栈顶。

singleTop和singleTask的区别:
singleTop模式每次只检测当前栈顶的activity是否是希望我们创建的,如果是就不用创建了,复用就可以了。
singleTask模式会检测栈中所有的activity的对象,找到就提到栈顶,将前面挡住的全部销毁

举例:手机浏览器

【singleInstance模式】

在这中加载模式下,系统保证无论从哪个task中启动目标activity,只会创建一个目标activity的实例,并且会使用
一个全新的task的栈来装载这个task的实例。
使用这种模式启动目标activity,也可以分为两种情况:
(1)如果将要启动的目标activity不存在,系统会先创建一个全新的task,加载创建目标activity的实例,并且会有一个
全新的task的栈来装载这个目标activity。
(2)如果将要启动的目标activity已经存在,无论它位于哪个应用程序中,无论他位于哪个task中,系统将会把这个
activity所在的task放置在前台,从而使这个activity显示出来。
注意:
采用singleInstance的模式加载的activity使用位于栈顶,并且在栈中只有这个activity。
举例: 来电显示页面,有道取词页面

intent

可以通过setAction进行页面跳转

Intent的概念和作用:

  1. 用于封装程序的调用“意图”
  2. 实现了两个activity之间的数据交互
  3. 各种应用程序组件(activity,service,broadcastReceiver)之间通信的重要媒介。

Intent的七大属性

  1. ComponentName :主要用于访问activity,进行显示意图的访问。
  2. action :表示想要启动的activity想要完成什么动作。进行隐士意图的访问。
  3. category :为action增加附加类别的信息。它是action大动作中的小动作。
  4. data :保存需要传递的数据的Uri格式。 Uri:统一资源标识符
  5. type :区分文件类型
  6. extras :保存需要传递的额外数据。
  7. flags :动态的配置activity的启动模式。

【ComponentName】:用于指定启动的组件

核心代码:

//完整的显示意图的跳转方法:
Intent intent3 = new Intent();
ComponentName cName = new ComponentName(MainActivity.this, SecondActivity.class);
intent3.setComponent(cName);
startActivity(intent3);

【action】:某个activity能够完成什么“动作”

intent当中定义的关于action的实参。
ACTION_MAIN:(android.intent.action.MAIN) Android的程序的入口
ACTION_VIEW:(android.intent.action.VIEW) 显示指定的数据
ACTION_EDIT:(android.intent.action.EDIT) 编辑指定的数据
ACTION_DIAL:(android.intent.action.DIAL) 显示拨号面板界面
ACTION_CALL:(android.intent.action.CALL) 直接呼叫data中所带的号码
ACTION_ANSWER:(android.intent.action.ANSWER) 接听来电
ACTION_SEND:(android.intent.action.SEND) 向其他人发送数据(彩信,email)
ACTION_SENDTO:(android.intent.action.SENDTO) 向其他人发送短信
ACTION_SEARCH:(android.intent.action.SEARCH) 执行搜索
ACTION_GET_CONTENT:(android.intent.action.GET_CONTENT) 让用户选择数据,并且返回所选数据

【Category】:类别属性

指明了执行action的分类,是action的子动作。

category常用的属性值:
CATEGORY_DEFAULT(android.intent.category.DEFAULT):Android系统中默认的执行方式, 按照普通的activity的执行方式来执行。
CATEGORY_HOME(android.intent.category.HOME):回到主屏页面
CATEGORY_LAUNCHER(android.intent.category.LAUNCHER):设置该组件为当前应用程序中优先级最高的activity, 通常是与ACTION_MAIN配合使用的。
CATEGORY_PREFERENCE:设置该组件为preference。
CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。

action和category在清单文件当中注册时,都是添加在activity的子元素<intent-fileter>当中的。
这个元素中可以包含多个action属性和多个category属性。

在应用程序中创建一个intent的属性时,只能设置一个action的属性,因为他使用的是setAction(str)的方法。
但是可以包含多个category的属性,因为他是使用addCategory(str)的方法的。

注意set和add的区别理解

【Data】:通常用于向action属性提供数据。

Data属性的值是一个uri的对象,URI的格式: scheme://host:port/path
scheme: 协议
host: 主机号
port: 端口号
path: 路径

系统内置的data属性的常量:

  1. tel: 号码的数据格式,后面跟着电话号码
  2. mailto: 邮件的数据格式,后面跟着邮件收件人的地址
  3. smsto: 短信的数据格式,后面跟着短信接受的号码
  4. content:// 内容数据格式,后面跟着需要读取的内容(结合内容提供者)
  5. file:/// 文件数据格式,后面跟着文件的路径,要有三个斜线。
  6. geo://lat,lon 经纬度数据格式,在地图上显示该经纬度指定的地址。
public void home(View v){
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        startActivity(intent);
    }
    
public void dial(View v){
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_DIAL);   //Intent.ACTION_DIAL
        Uri uri = Uri.parse("tel:18511698819");
        intent.setData(uri);
        startActivity(intent);
    }
    
public  void browser(View v) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        Uri data = Uri.parse("http://www.baidu.com/");
        intent.setData(data);
        startActivity(intent);
    }
public void map(View v){
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        Uri data = Uri.parse("geo://34.009,152.890");
        intent.setData(data);
        startActivity(intent);
    }
public void video(View v){
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        Uri uri = Uri.parse("file:///sdcard/and.mp4");
        intent.setDataAndType(uri, "video/*");
        startActivity(intent);
    }
public void music(View v){
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        Uri uri = Uri.parse("file:///sdcard/fly.mp3");
        intent.setDataAndType(uri, "audio/*");
        startActivity(intent);
    }
public void sms(View v){
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SENDTO);
        Uri uri = Uri.parse("smsto:18511690019");
        intent.setData(uri);
        intent.putExtra("sms_body", "今天的天气好晴朗!!");
        startActivity(intent);
    } 
public void sendEmail(View v){
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SEND);
        String bcc[] = {"[email protected]"};
        String cc[] = {"[email protected]","[email protected]"};
        intent.putExtra(Intent.EXTRA_BCC, bcc);
        intent.putExtra(Intent.EXTRA_CC, cc);
        intent.putExtra(Intent.EXTRA_SUBJECT, "今天的天气好晴朗");
        intent.putExtra(Intent.EXTRA_TEXT, "一起出去玩吧~~");
        intent.setType("message/*");
        startActivity(intent);
    }

读取Assets

  1. 通过context.getAssets()获取AssetManager对象
  2. 通过assetManager.open(fileName)获取输入流
  3. 使用ByteArrayOutputStream接收输入流并转成字节数组或者字符串

示例

   /**
     * 传入文件的路径 xzcontent/xzcontent.json
     * @param fname
     * @return
     */
    public String getAssetJson(String fname){
        //获取Asset文件管理者
        AssetManager assetManager = context.getAssets();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //打开文件
        try {
            InputStream is = assetManager.open(fname);
            //读流的数据
            int hasRead = 0;
            byte[] buf = new byte[1024];
            while ((hasRead = is.read(buf))!=-1){
                baos.write(buf, 0, hasRead);
            }
            baos.flush();
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return baos.toString();
    }

读取assets中的图片

使用BitmapFactory将byte数组转换为Bitmap对象,然后setImageBitmap即可
如下例

 // 读取asset文件夹当中的图片,显示在imageview上
    String fname = "xzlog/" + dao.getLogoname() + ".png";
    byte[] bytes = assetsUtils.getAssetByteArray(fname);
    //将字节数组转换成位图对象
    Bitmap bitmap =
            BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    vholder.iv.setImageBitmap(bitmap);