尾声
最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。
当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。
进阶学习视频
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
int which) {
dialog.dismiss();
}
});
builder.create().show();
} else {
// SD卡未扫描到离线地图
}
break;
case R.id.btnScan:
setMapNumberText();
break;
case R.id.layoutUpdateOnline:
Intent intentUpdate = new Intent(
OfflineBaiduMapUpdateActivity.this,
OfflineBaiduMapActivity.class);
startActivity(intentUpdate);
break;
default:
break;
}
}
}
/**
-
获取SD卡离线地图数目
-
@return
*/
private int getSDMapCount() {
int fileCount1 = checkFileNumber(pathFrom[0]);
int fileCount2 = checkFileNumber(pathFrom[1]);
int fileCount3 = checkFileNumber(pathFrom[2]);
int fileCount4 = checkFileNumber(pathFrom[3]);
if (fileCount1 > 0)
return fileCount1;
else if (fileCount2 > 0)
return fileCount2;
else if (fileCount3 > 0)
return fileCount3;
else if (fileCount4 > 0)
return fileCount4;
else
return -1;
}
private int checkFileNumber(String path) {
try {
File a = new File(path);
String[] file = a.list();
progressCopy.setMax(file.length);
if (file.length > 0) {
return file.length;
} else
return -1;
} catch (Exception e) {
return -1;
}
}
/**
-
复制整个文件夹内容
-
@param oldPath
-
String 原文件路径
-
@param newPath
-
String 复制后路径
-
@return boolean
*/
public boolean copyFolder(String oldPath, String newPath) {
boolean isok = true;
try {
(new File(newPath)).mkdirs(); // 如果文件夹不存在 则建立新文件夹
File a = new File(oldPath);
String[] file = a.list();
progressCopy.setMax(file.length);
if (file.length > 0) {
Message message = new Message();
message.what = 2;
copyHandler.sendMessage(message);
}
File temp = null;
for (int i = 0; i < file.length; i++) {
if (isActivityShow) {
if (oldPath.endsWith(File.separator)) {
temp = new File(oldPath + file[i]);
} else {
temp = new File(oldPath + File.separator + file[i]);
}
if (temp.isFile()) {
FileInputStream input = new FileInputStream(temp);
FileOutputStream output = new FileOutputStream(newPath
- “/” + (temp.getName()).toString());
byte[] b = new byte[1024 * 5];
int len;
while ((len = input.read(b)) != -1) {
output.write(b, 0, len);
}
output.flush();
output.close();
input.close();
}
// if (temp.isDirectory()) {// 如果是子文件夹
// copyFolder(oldPath + “/” + file[i], newPath + “/” +
// file[i]);
// }
MyLog.v(“Copy:” + file[i] + " Success");
progressCopy.setProgress(i);
Message message = new Message();
message.what = 3;
message.arg1 = i + 1;
message.arg2 = progressCopy.getMax();
copyHandler.sendMessage(message);
} else {
// 跳出循环,不进行后台拷贝
break;
}
}
// 更新Media Database
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse(“file://” + Constant.Path.BAIDU_OFFLINE_SUB)));
Message message = new Message();
message.what = 1;
copyHandler.sendMessage(message);
} catch (Exception e) {
Log.e(Constant.TAG,
“Copy Map form SD " + oldPath + " Error:” + e.toString());
isok = false;
Message message = new Message();
message.what = 0;
copyHandler.sendMessage(message);
}
return isok;
}
final Handler copyHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
Log.e(Constant.TAG, “There is no offline map!”);
textDetail.setVisibility(View.GONE);
textHint.setText(getResources().getString(
R.string.sd_has_no_map));
progressCopy.setVisibility(View.GONE);
btnStart.setVisibility(View.VISIBLE);
btnScan.setVisibility(View.VISIBLE);
// finish();
break;
case 1:
Log.e(Constant.TAG, “copy data success!”);
Intent i = new Intent();
setResult(RESULT_OK, i);
textHint.setText(getResources().getString(
R.string.import_sd_success));
textDetail.setVisibility(View.GONE);
progressCopy.setVisibility(View.GONE);
btnStart.setVisibility(View.VISIBLE);
btnScan.setVisibility(View.VISIBLE);
break;
case 2:
textHint.setText(getResources().getString(
R.string.importing_not_exist));
progressCopy.setVisibility(View.VISIBLE);
btnStart.setVisibility(View.GONE);
btnScan.setVisibility(View.GONE);
break;
case 3:
int now = msg.arg1;
int total = msg.arg2;
textDetail.setVisibility(View.VISIBLE);
textDetail.setText(now + “/” + total);
break;
case 4:
// textHint.setText(“正在检测SD卡是否有离线地图”);
break;
}
super.handleMessage(msg);
}
};
public class CopyThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < pathFrom.length; i++) {
if (!copyFolder(pathFrom[i], Constant.Path.BAIDU_OFFLINE_SUB)) {
} else {
Message message = new Message();
message.what = 4;
copyHandler.sendMessage(message);
Log.v(Constant.TAG, “Copy Map form SD Success, From:”
- pathFrom[i]);
break;
}
}
}
}
/**
- 导入离线地图包数据
*/
private MKOfflineMap mOffline = null;
public void importOfflineMapFromSDCard() {
mOffline = new MKOfflineMap();
mOffline.init(new MyMKOfflineMapListener());
int num = mOffline.importOfflineData();
Log.v(Constant.TAG, “ImportDataThread:Import Baidu Offline Map number:”
- num);
if (num == 0) {
// 没有导入离线包,可能是离线包放置位置不正确,或离线包已经导入过
} else {
// "成功导入 num 个离线包
}
// new Thread(new ImportDataThread()).start();
}
public class ImportDataThread implements Runnable {
@Override
public void run() {
}
}
class MyMKOfflineMapListener implements MKOfflineMapListener {
@Override
public void onGetOfflineMapState(int type, int state) {
switch (type) {
case MKOfflineMap.TYPE_DOWNLOAD_UPDATE:
MKOLUpdateElement update = mOffline.getUpdateInfo(state);
// 处理下载进度更新提示
if (update != null) {
// stateView.setText(String.format(“%s : %d%%”,
// update.cityName,
// update.ratio));
// updateView();
}
break;
case MKOfflineMap.TYPE_NEW_OFFLINE:
// 有新离线地图安装
break;
case MKOfflineMap.TYPE_VER_UPDATE:
// 版本更新提示
// MKOLUpdateElement e = mOffline.getUpdateInfo(state);
break;
}
}
}
@Override
protected void onStop() {
isActivityShow = false;
super.onStop();
}
}
5.在线更新离线地图:
package com.tchip.baidunavi.ui.activity;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.baidu.mapapi.map.offline.MKOLSearchRecord;
import com.baidu.mapapi.map.offline.MKOLUpdateElement;
import com.baidu.mapapi.map.offline.MKOfflineMap;
import com.baidu.mapapi.map.offline.MKOfflineMapListener;
import com.tchip.baidunavi.R;
import com.tchip.baidunavi.util.MyLog;
import com.tchip.baidunavi.util.NetworkUtil;
/**
-
安装后搜索仍需联网,但会节约达90%的流量
-
低分屏:L 高分屏:H (854x480 5’ 属于低分屏)
*/
public class OfflineBaiduMapActivity extends Activity implements
MKOfflineMapListener {
private MKOfflineMap mOffline = null;
private TextView cidView;
private TextView stateView;
private EditText cityNameView;
private Button btnSearch;
private RelativeLayout layoutBack, layoutDownload, layoutCity,
layoutImport;
private LinearLayout layoutSingleDownload;
private boolean isSingleDownShow = false;
/**
- 已下载的离线地图信息列表
*/
private ArrayList localMapList = null;
private LocalMapAdapter lAdapter = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_offline_baidumap);
mOffline = new MKOfflineMap();
mOffline.init(this);
initialLayout();
}
private void initialLayout() {
btnSearch = (Button) findViewById(R.id.btnSearch);
btnSearch.setOnClickListener(new MyOnClickListener());
layoutBack = (RelativeLayout) findViewById(R.id.layoutBack);
layoutBack.setOnClickListener(new MyOnClickListener());
layoutDownload = (RelativeLayout) findViewById(R.id.layoutDownload);
layoutDownload.setOnClickListener(new MyOnClickListener());
layoutCity = (RelativeLayout) findViewById(R.id.layoutCity);
layoutCity.setOnClickListener(new MyOnClickListener());
layoutImport = (RelativeLayout) findViewById(R.id.layoutImport);
layoutImport.setOnClickListener(new MyOnClickListener());
layoutSingleDownload = (LinearLayout) findViewById(R.id.layoutSingleDownload);
layoutSingleDownload.setVisibility(View.GONE);
cidView = (TextView) findViewById(R.id.cityid);
cityNameView = (EditText) findViewById(R.id.textCity);
stateView = (TextView) findViewById(R.id.state);
// ListView hotCityList = (ListView) findViewById(R.id.hotcitylist);
// ArrayList hotCities = new ArrayList();
// // 获取热闹城市列表
ArrayList records1 = mOffline.getHotCityList();
// if (records1 != null) {
// for (MKOLSearchRecord r : records1) {
// hotCities.add(r.cityName + “(” + r.cityID + “)” + " --"
// + this.formatDataSize(r.size));
// }
// }
// ListAdapter hAdapter = (ListAdapter) new ArrayAdapter(this,
// android.R.layout.simple_list_item_1, hotCities);
// hotCityList.setAdapter(hAdapter);
ListView allCityList = (ListView) findViewById(R.id.allcitylist);
// 获取所有支持离线地图的城市
final ArrayList allCities = new ArrayList();
ArrayList records2 = mOffline.getOfflineCityList();
if (records1 != null) {
for (MKOLSearchRecord r : records2) {
allCities.add(r.cityName + “(” + r.cityID + “)” + " --"
- this.formatDataSize(r.size));
}
}
ListAdapter aAdapter = (ListAdapter) new ArrayAdapter(this,
R.layout.offline_map_all_city_list_item, R.id.textAllCityList,
allCities);
allCityList.setAdapter(aAdapter);
allCityList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (NetworkUtil.isNetworkConnected(getApplicationContext())) {
int startIndex = allCities.get(position).indexOf(“(”) + 1;
int endIndex = allCities.get(position).indexOf(“)”);
String clickId = allCities.get(position).substring(
startIndex, endIndex);
MyLog.v(“Offline Map id:” + clickId);
mOffline.start(Integer.parseInt(clickId));
Toast.makeText(
getApplicationContext(),
getResources().getString(R.string.start_download)
-
“:”
-
allCities.get(position).substring(0,
startIndex - 1), Toast.LENGTH_SHORT)
.show();
} else {
NetworkUtil.noNetworkHint(getApplicationContext());
}
}
});
LinearLayout cl = (LinearLayout) findViewById(R.id.citylist_layout);
LinearLayout lm = (LinearLayout) findViewById(R.id.localmap_layout);
lm.setVisibility(View.GONE);
cl.setVisibility(View.VISIBLE);
// 获取已下过的离线地图信息
localMapList = mOffline.getAllUpdateInfo();
if (localMapList == null) {
localMapList = new ArrayList();
}
ListView localMapListView = (ListView) findViewById(R.id.localmaplist);
lAdapter = new LocalMapAdapter();
localMapListView.setAdapter(lAdapter);
}
/**
-
设置下载单个城市离线地图是否可见
-
@param isShow
*/
private void setSingleDownShow(boolean isShow) {
if (!isShow) {
layoutSingleDownload.setVisibility(View.GONE);
isSingleDownShow = false;
} else {
layoutSingleDownload.setVisibility(View.VISIBLE);
isSingleDownShow = true;
}
}
class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSearch:
// 搜索离线城市
if (NetworkUtil.isNetworkConnected(getApplicationContext())) {
ArrayList records = mOffline
.searchCity(cityNameView.getText().toString());
if (records == null || records.size() != 1) {
Toast.makeText(
getApplicationContext(),
getResources()
.getString(R.string.no_match_city),
Toast.LENGTH_SHORT).show();
return;
}
setSingleDownShow(true);
cidView.setText(String.valueOf(records.get(0).cityID));
} else {
NetworkUtil.noNetworkHint(getApplicationContext());
}
break;
case R.id.layoutBack:
onBackKeyPressed();
break;
case R.id.layoutDownload:
// 下载管理列表
LinearLayout cl = (LinearLayout) findViewById(R.id.citylist_layout);
LinearLayout lm = (LinearLayout) findViewById(R.id.localmap_layout);
lm.setVisibility(View.VISIBLE);
cl.setVisibility(View.GONE);
break;
case R.id.layoutCity:
// 城市列表
LinearLayout cls = (LinearLayout) findViewById(R.id.citylist_layout);
LinearLayout lms = (LinearLayout) findViewById(R.id.localmap_layout);
lms.setVisibility(View.GONE);
cls.setVisibility(View.VISIBLE);
break;
case R.id.layoutImport:
importFromSDCard();
break;
default:
break;
}
}
}
/**
-
开始下载
-
@param view
*/
public void start(View view) {
if (NetworkUtil.isNetworkConnected(getApplicationContext())) {
Toast.makeText(this,
getResources().getString(R.string.offline_download_start),
Toast.LENGTH_SHORT).show();
startDownloadCityId = Integer
.parseInt(cidView.getText().toString());
new Thread(new StartDownloadThread()).start();
} else {
NetworkUtil.noNetworkHint(getApplicationContext());
}
}
private int startDownloadCityId = 1; // 要下载的城市ID
/**
- 下载地图线程
*/
private class StartDownloadThread implements Runnable {
@Override
public void run() {
// 启动下载指定城市ID的离线地图,离线地图下载服务仅当wifi连接正常时可用
mOffline.start(startDownloadCityId);
startDownloadCityId = 1; // 重置
Message messageStartDownload = new Message();
messageStartDownload.what = 1;
startDownloadHandler.sendMessage(messageStartDownload);
}
}
final Handler startDownloadHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
updateView();
break;
default:
break;
}
}
};
/**
-
暂停下载
-
@param view
*/
public void stop(View view) {
int cityid = Integer.parseInt(cidView.getText().toString());
mOffline.pause(cityid);
Toast.makeText(this,
getResources().getString(R.string.offline_download_pause),
Toast.LENGTH_SHORT).show();
updateView();
}
/**
-
删除离线地图
-
@param view
*/
public void deleteMapByCityId(int cityId) {
deleteMapId = cityId;
new Thread(new DeleteMapThread()).start();
Toast.makeText(this,
getResources().getString(R.string.offline_download_delete),
Toast.LENGTH_SHORT).show();
updateView();
}
private int deleteMapId = 1; // 要删除的地图ID
/**
- 删除地图线程
*/
private class DeleteMapThread implements Runnable {
@Override
public void run() {
mOffline.remove(deleteMapId);
deleteMapId = 1;
}
}
/**
-
从SD卡导入离线地图安装包
-
存放位置:USB存储器/BaiduMapSDK/vmp/l/zhongshan_187.dat
*/
public void importFromSDCard() {
new Thread(new ImportOfflineMapThread()).start();
}
private class ImportOfflineMapThread implements Runnable {
@Override
public void run() {
int mapNum = mOffline.importOfflineData();
String msg = “”;
if (mapNum == 0) {
Message messageNoMap = new Message();
messageNoMap.what = 1;
importOfflineMapHandler.sendMessage(messageNoMap);
} else {
Message messageImport = new Message();
messageImport.what = 2;
importOfflineMapHandler.sendMessage(messageImport);
}
}
}
final Handler importOfflineMapHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1: // 未导入离线地图包
AlertDialog.Builder builder = new Builder(
OfflineBaiduMapActivity.this);
builder.setMessage(getResources().getString(
R.string.not_import_offline_map));
builder.setTitle(getResources().getString(R.string.hint));
builder.setPositiveButton(
getResources().getString(R.string.confirm),
new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
});
builder.create().show();
break;
case 2:
AlertDialog.Builder builderImport = new Builder(
OfflineBaiduMapActivity.this);
builderImport.setMessage(getResources().getString(
R.string.import_success_without_num));
builderImport.setTitle(getResources().getString(R.string.hint));
builderImport.setPositiveButton(
getResources().getString(R.string.confirm),
new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
});
builderImport.create().show();
updateView();
break;
default:
最后我想说
为什么很多程序员做不了架构师?
1、良好健康的职业规划很重要,但大多数人都忽略了
2、学习的习惯很重要,持之以恒才是正解。
3、编程思维没能提升一个台阶,局限在了编码,业务,没考虑过选型、扩展
4、身边没有好的架构师引导、培养。所处的圈子对程序员的成长影响巨大。
金九银十面试季,跳槽季,整理面试题已经成了我多年的习惯!在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
Click(DialogInterface dialog,
int which) {
dialog.dismiss();
}
});
builder.create().show();
break;
case 2:
AlertDialog.Builder builderImport = new Builder(
OfflineBaiduMapActivity.this);
builderImport.setMessage(getResources().getString(
R.string.import_success_without_num));
builderImport.setTitle(getResources().getString(R.string.hint));
builderImport.setPositiveButton(
getResources().getString(R.string.confirm),
new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
});
builderImport.create().show();
updateView();
break;
default:
最后我想说
为什么很多程序员做不了架构师?
1、良好健康的职业规划很重要,但大多数人都忽略了
2、学习的习惯很重要,持之以恒才是正解。
3、编程思维没能提升一个台阶,局限在了编码,业务,没考虑过选型、扩展
4、身边没有好的架构师引导、培养。所处的圈子对程序员的成长影响巨大。
金九银十面试季,跳槽季,整理面试题已经成了我多年的习惯!在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
[外链图片转存中…(img-vBV7l6Hq-1715648683529)]
里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!