首页
网站首页
公司简介
资讯中心
推荐内容
返回顶部
利用高德地图API打造基于LBS的Android应用,java后台面试题整理
发布时间:2020-03-23 10:17
浏览次数:

最近做了一个小的项目,主要功能是获取用户的定位等相关数据用于分析,在开发过程中使用了高德地图SDK,这里结合自己遇到的问题总结一些常见的API的用法,方便以后参考使用。

虽然使用AndroidStudio开发并使用git管理代码已经有很长时间,但是第一次提交项目到git依然会很不顺利,网上的文章或许因为所使用版本比较老,并不一定完全凑效,因此写此笔记做下整理。

根据@会发光的二极管的建议,所有问题均已整理到github地址 : https://github.com/wgd12389/java-server-interview-questions 欢迎各位吧自己遇到的问题进行总结,提pr

一、前言

提到 APK 更新,大家可能会想到友盟更新,市场上已有数万款应用在使用友盟自动更新的服务。但友盟于 2016 年 10 月 15 日起停止了更新服务。那么我们需要自己处理 APK 更新的业务。

本篇主要讲解以下知识点:

  • 使用 DownloadManager 更新

  • 基于 RxJava 和 retrofit 扩展的 Android 线程安全 http 请求库下载 APK 更新

  • 热更新

我们来啾啾第一个知识点。

一、申请Key二、配置工程三、定位SDK的使用四、地图SDK的使用五、总结

首先准备工作git客户端和as客户端是不可少的工具,本次使用的是as2.2.2和git2.10.2;

Arrays.sort实现原理和Collection实现原理foreach和while的区别线程池的种类,区别和使用场景分析线程池的实现原理和线程的调度过程线程池如何调优线程池的最大线程数目根据什么确定动态代理的几种方式HashMap的并发问题了解LinkedHashMap的应用吗反射的原理,反射创建类实例的三种方式是什么?cloneable接口实现原理,浅拷贝or深拷贝Java NIO使用hashtable和hashmap的区别及实现原理,hashmap会问到数组索引,hash碰撞怎么解决arraylist和linkedlist区别及实现原理反射中,Class.forName和ClassLoader区别String,Stringbuffer,StringBuilder的区别?有没有可能2个不相等的对象有相同的hashcode简述NIO的最佳实践,比如netty,minaTreeMap的实现原理

DownloadManager 更新

Android 2.3(API level 9)开始 Android 用系统服务的方式提供了DownloadManager 来优化处理长时间的下载操作。DownloadManager 对后台下载,下载状态回调,断点续传,下载环境设置,下载文件的操作等都有很好的支持。

本篇基于 Android 4.0 ~7.0 (SDK 14~24) 开发,众所周知 Android 6.0 的 Runtime Permissions 。

请参考Android 6.0 运行时权限封装之路

下面具体来看看 DownloadManager 更新的具体流程。

下载文件需要使用到网络权限,文件读写权限:

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

getPackageManager().getPackageInfo(getPackageName.versionName;

www.64222.com ,后台需要提供查询最新版本号的接口,获取接口数据与当前版本号对比,判定是否需要更新。

DownloadManager manager = (DownloadManager) appContext.getSystemService(Context.DOWNLOAD_SERVICE);

下面来看看 DownloadManager 提供哪些接口:

  • public long enqueue(Request request) 执行下载,返回 downloadId,downloadId 可用于后面查询下载信息。若网络不满足条件、Sdcard 挂载中、超过最大并发数等异常则会等待下载,正常则直接下载。

  • int remove(long… ids) 删除下载,若下载中取消下载。会同时删除下载文件和记录。参数 ids 为 enqueue 返回的 downloadId 集合。

  • Cursor query(Query query) 查询下载信息。

  • getMaxBytesOverMobile(Context context) 返回移动网络下载的最大值

  • rename(Context context, long id, String displayName) 重命名已下载项的名字

  • getRecommendedMaxBytesOverMobile(Context context) 获取建议的移动网络下载的大小

  • 利用高德地图API打造基于LBS的Android应用,java后台面试题整理。其它:通过查看代码我们可以发现还有个 CursorTranslator 私有静态内部类。这个类主要对 Query 做了一层代理。将 DownloadProvider 和 DownloadManager之间做了个映射。

接着来看看 DownloadManager.Request 的请求参数。

//获取Request的实例对象 DownloadManager.Request request = new DownloadManager.Request(Uri.parse;

显示信息:

//设置一些基本显示信息 request.setTitle; //通知栏标题 request.setDescription(description);//通知栏内容 request.setMimeType("application/vnd.android.package-archive");//文件的类型

网络类型:

//NETWORK_MOBILE移动网络//NETWORK_WIFI wifi网络//NETWORK_BLUETOOTH 蓝牙req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);

通知栏显示类型:

 request.setNotificationVisibility(DownloadManager.Request .VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
  • VISIBILITY_HIDDEN 下载UI不会显示,也不会显示在通知中,如果设置该值,需要声明android.permission.DOWNLOAD_WITHOUT_NOTIFICATION
  • VISIBILITY_VISIBLE 当处于下载中状态时,可以在通知栏中显示;当下载完成后,通知栏中不显示
  • VISIBILITY_VISIBLE_NOTIFY_COMPLETED 当处于下载中状态和下载完成时状态,均在通知栏中显示
  • VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION 只在下载完成时显示在通知栏中。

文件的保存位置:

  • 保存到外部环境的私有目录:file:///storage/emulated/0/Android/data/your-package/files/Download/app.apk
 request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, "app.apk");
  • 保存到外部环境的共有目录: file:///storage/emulated/0/Download/app.apk
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "app.apk");
  • 自定义文件路径
setDestinationUri

添加请求下载的网络链接的http头,比如User-Agent,gzip压缩等:

request.addRequestHeader(String header, String value)

漫游:

//true 允许//false 不允许request.setAllowedOverRoaming;

其他:

setAllowedOverMetered(boolean allow) //是否允许计量setRequiresCharging(boolean requiresCharging)//是否在充电环境下setVisibleInDownloadsUi(boolean isVisible)//是否显示下载界面...

下面是本文创建Request的示例代码:

 request.setTitle; request.setDescription(description); //在通知栏显示下载进度 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request .VISIBILITY_VISIBLE_NOTIFY_COMPLETED); } request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); request.setDestinationInExternalPublicDir(SAVE_APP_LOCATION, SAVE_APP_NAME);

DownloadManager manager = (DownloadManager) appContext.getSystemService(Context.DOWNLOAD_SERVICE);manager.enqueue;

DownloadManager 下载工具并没有提供相应的回调接口用于返回实时的下载进度状态。可以通过 DownloadManager.query 方法进行查询,该方法返回一个 Cursor 对象,具体看以下代码:

 private void queryDownloadManager { DownloadManager mDownloadManager = (DownloadManager) this.getSystemService(Context.DOWNLOAD_SERVICE); DownloadManager.Query query = new DownloadManager.Query().setFilterById; //可以对query设置一些过滤条件 //setFilterById(long… ids)根据下载id进行过滤 //setFilterByStatus(int flags)根据下载状态进行过滤 Cursor cursor = mDownloadManager.query; if (cursor != null) { while (cursor.moveToNext { String bytesDownload = cursor.getString(cursor.getColumnIndex(DownloadManager .COLUMN_BYTES_DOWNLOADED_SO_FAR)); String description = cursor.getString(cursor.getColumnIndex(DownloadManager .COLUMN_DESCRIPTION)); String cid = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_ID)); String localUri = cursor.getString(cursor.getColumnIndex(DownloadManager .COLUMN_LOCAL_URI)); String mimeType = cursor.getString(cursor.getColumnIndex(DownloadManager .COLUMN_MEDIA_TYPE)); String title = cursor.getString(cursor.getColumnIndex(DownloadManager .COLUMN_TITLE)); String status = cursor.getString(cursor.getColumnIndex(DownloadManager .COLUMN_STATUS)); String totalSize = cursor.getString(cursor.getColumnIndex(DownloadManager .COLUMN_TOTAL_SIZE_BYTES)); Log.i("MainActivity", "bytesDownload:" + bytesDownload); Log.i("MainActivity", "description:" + description); Log.i("MainActivity", "cid:" + cid); Log.i("MainActivity", "localUri:" + localUri); Log.i("MainActivity", "mimeType:" + mimeType); Log.i("MainActivity", "title:" + title); Log.i("MainActivity", "status:" + status); Log.i("MainActivity", "totalSize:" + totalSize); } } }

本篇示例的打印结果如下:

www.64222.com 1man

当用户点击通知栏中的下载列表时,系统会发出 ACTION_NOTIFICATION_CLICKED 事件广播;下载完成时会发出 ACTION_DOWNLOAD_COMPLETE 事件广播,那么我们就可以实现一个广播接收器处理点击和完成时的状态。请看下面代码:

 public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) { installApk; } else if (intent.getAction().equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)) { //Toast.makeText(context, "Clicked", Toast.LENGTH_SHORT).show(); } }

如文本下载 apk 文件,下载完成时就自动安装,使用意图进行 apk 安装:

 // 安装Apk private void installApk(Context context) { try { Intent i = new Intent(Intent.ACTION_VIEW); String filePath = DownloadManagerUtils.APP_FILE_NAME; i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android" + ".package-archive"); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity; } catch (Exception e) { Log.e(TAG, "安装失败"); e.printStackTrace(); } }

DownloadManager 更新就讲到这里了,源码在文章的后面会附上。

使用高德地图SDK的步骤主要如下:

git:https://git-scm.com/downloads

JVM相关

类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,他们的执行顺序JVM内存分代Java 8的内存分代改进JVM垃圾回收机制,何时触发MinorGC等操作jvm中一次完整的GC流程是怎样的,重点讲讲对象如何晋升到老年代,几种主要的jvm参数等你知道哪几种垃圾收集器,各自的优缺点,重点讲下cms,g1新生代和老生代的内存回收策略Eden和Survivor的比例分配等深入分析了Classloader,双亲委派机制JVM的编译优化对Java内存模型的理解,以及其在并发中的应用指令重排序,内存栅栏等OOM错误,stackoverflow错误,permgen space错误JVM常用参数tomcat结构,类加载器流程volatile的语义,它修饰的变量一定线程安全吗g1和cms区别,吞吐量优先和响应优先的垃圾收集器选择说一说你对环境变量classpath的理解?如果一个类不在classpath下,为什么会抛出ClassNotFoundException异常,如果在不改变这个类路径的前期下,怎样才能正确加载这个类?说一下强引用、软引用、弱引用、虚引用以及他们之间和gc的关系

基于 RxJava 和 retrofit 扩展的 Android 线程安全 http 请求库下载 APK 更新

针对 DownloadManager 更新,我们还可以通过 http 请求库下载 apk 文件进行更新。

提到 http 请求库,就不得不提到 Novate 库,功能非常强大,使用便利,看看它有哪些功能:

  • 加入基础API,减少Api冗余
  • 支持离线缓存
  • 支持多种方式访问网络(get,put,post ,delete)
  • 支持Json字符串,表单提交
  • 支持文件下载和上传
  • 支持请求头统一加入
  • 支持对返回结果的统一处理
  • 支持自定义的扩展API
  • 支持统一请求访问网络的流程控制

Novate官方文档

我下载了源码,并修改了进度条的接口。下载文件相信大家都比较熟悉了,我这里就不再细讲了。如果有什么疑问请链接上面地址查看。

以下给出本篇用到的消息代码:

 private NotificationCompat.Builder buildNotification() { final Resources res = mContext.getResources(); // This image is used as the notification's large icon (thumbnail). // TODO: Remove this if your notification has no relevant thumbnail. final Bitmap picture = BitmapFactory.decodeResource(res, R.mipmap.ic_launcher); return new NotificationCompat.Builder. setContentTitle("更新包下载中...") .setTicker("准备下载...") .setProgress(100, 0, false) .setContentText(String.format(mContext.getResources() .getString(R.string.apk_progress), 0) + "%") .setLargeIcon .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setWhen(System.currentTimeMillis .setSmallIcon(R.mipmap.ic_launcher) .setAutoCancel; } //更新消息进度 public void showProgressNotification(int progress) { if (mBuilder == null) { mBuilder = buildNotification(); } Notification notification = mBuilder.setProgress(100, progress, false) .setContentText(String.format(mContext.getResources().getString(R.string .apk_progress), progress) + "%") .build(); notify(mContext, notification); }

如果你还想了解更多 Notification 实现显示下载进度,请连接 Android中使用Notification实现应用更新显示下载进度

 private void downloadApk() { RetrofitClient.getInstance.createBaseApi() .download(DOWN_URL, new CallBack() { @Override public void onError(Throwable e) { Log.e("HttpActivity", "onError--------2222" + e.getMessage; mHttpNotification.removeProgressNotification(); } @Override public void onStart() { super.onStart(); mHttpNotification.showProgressNotification; } @Override public void onSucess(String path, String name, long fileSize) { mHttpNotification.removeProgressNotification(); installApk(HttpActivity.this); } @Override public void onProgress(int progress) { super.onProgress; mCircleProgressView.setProgress; mHttpNotification.showProgressNotification; } }); }

如果你还有疑问,在文章结尾处下载源码进行查看。

更新全过程效果图:

www.64222.com 2app

友情链接: 网站地图
Copyright © 2015-2019 http://www.nflfreepicks.net. 新葡萄京娱乐场网址有限公司 版权所有