day 8-9 面试题:泛型、Android8.0适配

本文深入探讨Java泛型的概念及其在实际编程中的应用,并详细解析Android8.0的重要特性及适配策略,包括通知、广播、服务等方面的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面试题:

1. 泛型:  
	1. 什么是泛型,能解决什么问题  
	2. 说说java中的泛型的工作机制  
	3. 在泛型中extends和super关键字的区别     
2. Android 8.0适配?

1. 面试题解题

1.1 泛型

1.1.1 什么是泛型

泛型是Java SE1.5引入的,泛型本质是参数化类型,将所操作的数据类型指定为一个参数,该参数类型可以用在类、接口、方法中。分别叫做泛型类、泛型接口、泛型方法。

  1. 泛型类

    泛型类用于类的定义中,比如List,Set,Map等。

     /**
      * 此处的T是泛型标识,可以是任意的大写字母
      * 在调用时必须指定T的具体类型:new People<Integer>(60);
      */
     
     public class People<T> {
         private T t;
     
         public People(T t) {
             this.t = t;
         }
     }
    
  2. 泛型接口

    同泛型类一样,用于接口的定义中,见下面的例子。

     public interface Age<T> {
         T getAge();
     }
    
     public class People implements Age<Integer>{
    
         @Override
         public Integer getAge() {
             return new Random().nextInt(100);
         }
     }
    
  3. 泛型方法

    需要在方法中使用的泛型如果没有在类和接口中定义过,那么必须在方法中定义后才可使用。

     /**
      * public 和返回值E中间的类型申明是必需的,因为只有申请了该类型,才能在方法中使用
      */
     public <E> E getInfomation(Class<E> eClass) throws IllegalAccessException, InstantiationException {
         E e = eClass.newInstance();
         return e;
     }
    
1.1.2 泛型能解决什么问题
  1. 在编译时检查参数类型,避免异常发生
  2. 消除强制类型转换
  3. 提高代码复用率
1.1.3 说说java中的泛型的工作机制

Java泛型是编译时技术,在运行时不包含泛型信息,仅仅是Class的实例中包含类型参数的定义信息。它是通过Java编译器的擦除前端来实现的,可以认为是从源码到源码的转换,从泛型源码转为非泛型的代码。它有几个特点:

  1. 不能依靠泛型做类型转换
  2. 同一个泛型类,在被调用时类类型是一样的,无论传入的泛型类是否一样
1.1.4 在泛型中extends和super关键字的区别

使用底下的例子来说明,extends是上界通配符,指定类的上边界。它只能取,不能存,因为你不清楚具体存的是哪个实现类,所以无法存入。
super是下界通配符,指定类的下边界,它只能存,不能取,因为根本不清楚取出的数据是什么实现类,只能指定为Object。

class Food{}
class Fruit extends Food{}

class Apple extends Fruit{}

class Banana extends Fruit{}

public void testExtends(List<? extends Fruit> fruits){
    // fruits.add(new Apple());
    Fruit fruit = fruits.get(0);
}

public void testSuper(List<? super Fruit> list){
    // Object object = list.get(0);
    list.add(new Fruit());
}

1.2 Android 8.0适配?

1.2.1 Android8.0 通知适配

Android 8.0加入了ChannelId和ChannelGroup的概念,如果在创建通知的时候不加ChannelId,通知是不会被唤起的。

  1. 创建小组,这个步骤可有可无

  2. 创建ChannelId(为了简单,都简写写死,如果创建了小组,需要给ChannelId配置GroupId)

    NotificationChannel notificationChannel = new NotificationChannel("track_id", "track_name", NotificationManager.IMPORTANCE_LOW);
    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.createNotificationChannel(notificationChannel);
    
  3. 在构建通知时,加入ChannelId(比以往多加一个参数ChannelId)

    Notification notification = new Notification.Builder(this, "track_id").build();
    
1.2.2 广播限制

Android 8.0的应用无法在其清单文件中注册隐式广播接收器。

两种方案:

  1. 动态注册广播
  2. 指定包名,作为显示广播发送
1.2.3 后台服务适配

Android 8.0 对应用在后台执行的操作增加了限制,当应用处于后台时,不允许再启动服务。Android8.0提供了方法,在后台可以创建前台服务,下面看下步骤

  1. 启动前台服务

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
     	context.startForegroundService(service);
     }else{
     	context.startService(service);
     }
    
  2. 建立前台服务通知并调用startForeground(1,notification)

    如果是IntentService,这部分逻辑需要加到onHandleIntent中,因为onCreate并不是每次调用startService都会调用。

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
     	NotificationChannel notificationChannel = new NotificationChannel("track_id", "track_name", NotificationManager.IMPORTANCE_LOW);
     	NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
     	notificationManager.createNotificationChannel(notificationChannel);
     	Notification notification = new Notification.Builder(this, "track_id").build();
     	startForeground(1,notification);
     }
    
  3. 关闭前台服务

     service.stopForeground(true);
    
1.2.4 apk安装权限

Android 8.0 去除允许未知来源选项,需要用户手动确认,如果没有适配,覆盖安装时直接闪退。

  1. 最简单的解决方式就是,在Manifest文件中配置请求安装权限,这样在app调用安装界面时,系统会询问用户授权。

  2. 当然,你可以可以做的更复杂一些。

    1. 清单文件中配置REQUEST_INSTALL_PACKAGES权限

    2. 调用packageManager.canRequestPackageInstalls()获取是否已有该权限

       PackageManager packageManager = getApplicationContext().getPackageManager();
       boolean canInstallApk = packageManager.canRequestPackageInstalls();
      
    3. 如果没有权限,则弹框提示,点击确定跳转用户授权页面(一般更多的是使用startActivityForResult,授权完成继续安装)

       Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
       startActivity(intent);
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值