前言
这篇文章由知识点和大厂面试题组成
由于笔试和面试过去时间较久,很多细节都已记不清楚,所以下面写的笔试/面试经历只挑出了其中印象深刻的部分,并非完整的笔试/面试经历。关于常考的笔试/面试题目,我已整理并放在了石墨文档和GIthub上了,如有需要,敬请参考【Android方向面试、笔试知识整理】。文章过长但是都是满满的干货,要是不方便你学习的话,我已经整理成了一份PDF,需要的可以点击上面链接领取!
目录
-
Android总结
-
Android四大组件
-
Activity生命周期
-
添加网络权限
-
Intent Bundle--回转值跳转
-
显性意图
-
隐性意图
-
AndroidManifest.xml修改
-
然后
-
带Bundle跳转
-
跳转
-
接收
-
带Bundle传值并回传
-
跳转
-
过渡动画
-
View移动动画
-
得到ip
-
判断网络连接
-
判断方法
-
判断并弹到设置
-
中英文切换
-
资源管理
-
Anim/ 创建
-
HashMap排序
-
集合排序
-
遍历
-
HTTP类 与 获取数据方法--网络框架
-
在项目清单文件中添加
-
HTTP类
-
获取数据方法
-
JSONArray 转数值的方法
-
GreenDao Application类 和 数据库管理类--数据库框架(保险起见 原始数据库需要看一下)
-
添加依赖
-
Project build.gradle:
-
app build.gradle:
-
实体类
-
建entity包放实体类
-
Ctrl+F9后
-
并多出三个类
-
项目结构
-
编写MyApplication类
-
在项目清单文件中添加
-
编写GreenDaoManager数据库管理类
-
AlertDialog AlertDialog.Builder--弹出框
-
默认弹出框
-
单选弹出框
-
1
-
2
-
多选弹出框
-
ViewPage 的监听 Fragment--碎片以及小圆点
-
布局XMl
-
Fragment适配器
-
加入Fragment
-
滑动viewpage小圆点变化
-
点击小圆点Fragment viewpage发生变化
-
TableLayout--表格布局与传数据进表格
-
Xml
-
传数据进表
-
Handler Runnable--线程与更新UI
-
主体代码
-
开启线程
-
关闭线程
-
SimpleDateFormat--获得本地时间 年月日时分秒星期的格式
-
主体代码
-
SharedPreferences.Editor--写入本地
-
getSharedPreferences()--获取本地缓存
-
VideoView MediaController --视频组件与进度条组件的搭配
-
获取网页代码路径 与视频文件路径
-
网页代码路径
-
视频文件路径
-
LayoutParams --设置View的大小
-
Spinner --下拉框的适配和监听
-
适配
-
监听
-
Switch --开关的适配和监听
-
xml文件
-
监听
-
ExtendableListView --列表视图的适配
-
Xml
-
父视图group_item
-
子视图 child_item
-
适配器
-
适配
-
监听
-
Timer-TimerTask定时器
-
Handler定时器
-
NotificationManager Notification--通知栏的使用
-
shape --简单的图形框绘画
-
CalendarView --日历控件 监听
-
Xml
-
监听
-
include ViewStub --包含视图和延时包含视图的使用
-
include
-
ViewStub
-
Xml
-
延时加载
-
组件显示与隐藏
-
显示
-
隐藏
-
导入包的方法
-
Fragment中使用getFragmentManager()嵌入布局 在activity中
-
SimpleAdapter ArrayAdapter 的使用
-
ArrayAdapter
-
SimpleAdapter
-
ProgressBar的使用
-
Xml
-
Style
-
属性
-
退出程序
-
还有一部分没有整理
-
MPAndroidChart--画图
-
EChart--画图
-
Animation--出入场动画的使用
-
等等
-
配张图自己感受
Android总结
为本人学习时小小的总结 比较建议初学者观看
Android四大组件
Android开发四大组件分别是:活动(Activity):用于表现功能。
服务(Service):后台运行服务,不提供界面呈现。
广播接收器(BroadcastReceiver):用于接收广播。
内容提供商(ContentProvider):支持在多个应用中存储和读取数据,相当于数据库。
Activity生命周期
onCreate : 该方法是在Activity被创建时回调,它是生命周期第一个调用的方法,我们在创建Activity时一般都需要重写该方法,然后在该方法中做一些初始化的操作,如通过setContentView设置界面布局的资源,初始化所需要的组件信息等。
onStart : 此方法被回调时表示Activity正在启动,此时Activity已处于可见状态,只是还没有在前台显示,因此无法与用户进行交互。可以简单理解为Activity已显示而我们无法看见摆了。
onResume : 当此方法回调时,则说明Activity已在前台可见,可与用户交互了(处于前面所说的Active/Running形态),onResume方法与onStart的相同点是两者都表示Activity可见,只不过onStart回调时Activity还是后台无法与用户交互,而onResume则已显示在前台,可与用户交互。当然从流程图,我们也可以看出当Activity停止后(onPause方法和onStop方法被调用),重新回到前台时也会调用onResume方法,因此我们也可以在onResume方法中初始化一些资源,比如重新初始化在onPause或者onStop方法中释放的资源。
onPause : 此方法被回调时则表示Activity正在停止(Paused形态),一般情况下onStop方法会紧接着被回调。但通过流程图我们还可以看到一种情况是onPause方法执行后直接执行了onResume方法,这属于比较极端的现象了,这可能是用户操作使当前Activity退居后台后又迅速地再回到到当前的Activity,此时onResume方法就会被回调。当然,在onPause方法中我们可以做一些数据存储或者动画停止或者资源回收的操作,但是不能太耗时,因为这可能会影响到新的Activity的显示——onPause方法执行完成后,新Activity的onResume方法才会被执行。
onStop : 一般在onPause方法执行完成直接执行,表示Activity即将停止或者完全被覆盖(Stopped形态),此时Activity不可见,仅在后台运行。同样地,在onStop方法可以做一些资源释放的操作(不能太耗时)。
onRestart :表示Activity正在重新启动,当Activity由不可见变为可见状态时,该方法被回调。这种情况一般是用户打开了一个新的Activity时,当前的Activity就会被暂停(onPause和onStop被执行了),接着又回到当前Activity页面时,onRestart方法就会被回调。
onDestroy :此时Activity正在被销毁,也是生命周期最后一个执行的方法,一般我们可以在此方法中做一些回收工作和最终的资源释放
onCreate():
当我们点击activity的时候,系统会调用activity的oncreate()方法,在这个方法中我们会初始化当前布局setContentLayout()方法。
onStart():
onCreate()方法完成后,此时activity进入onStart()方法,当前activity是用户可见状态,但没有焦点,与用户不能交互,一般可在当前方法做一些动画的初始化操作。
onResume():
onStart()方法完成之后,此时activity进入onResume()方法中,当前activity状态属于运行状态 (Running),可与用户进行交互。
onPouse()
当另外一个activity覆盖当前的acitivty时,此时当前activity会进入到onPouse()方法中,当前activity是可见的,但不能与用户交互状态。
onStop()
onPouse()方法完成之后,此时activity进入onStop()方法,此时activity对用户是不可见的,在系统内存紧张的情况下,有可能会被系统进行回收。所以一般在当前方法可做资源回收。
onDestory()
onStop()方法完成之后,此时activity进入到onDestory()方法中,结束当前activity。
onRestart()
onRestart()方法在用户按下home()之后,再次进入到当前activity的时候调用。调用顺序onPouse()->onStop()->onRestart()->onStart()->onResume().
添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
Intent Bundle–回转值跳转
显性意图
Intent intent1 = new Intent(this, LoginActivity.class);
intent1.putExtra("one", "one");
intent1.putExtra("two", "two");
startActivity(intent1);
隐性意图
AndroidManifest.xml修改
<intent-filter>
<action android:name="com.example.Login" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
然后
Intent intent = new Intent();
intent.setAction("com.example.Login");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("zh", "张三");
intent.putExtra("pass", "123456");
startActivity(intent);
带Bundle跳转
跳转
Intent intent = new Intent(this, LoginActivity.class);
Bundle bundle = new Bundle();
bundle.putString("a", "aaa");
intent.putExtras(bundle);
startActivity(intent);
接收
Bundle bundle1 = getIntent().getExtras();
bundle1.getString("a");
带Bundle传值并回传
跳转
Intent intent = new Intent(this, LoginActivity.class);
Bundle bundle = new Bundle();
bundle.putString("a", "aaa");
intent.putExtras(bundle);
startActivityForResult(intent,1);
关闭跳转页面执行
@Override
public void startActivityForResult(Intent intent, int requestCode) {
super.startActivityForResult(intent, requestCode);
if (requestCode==1){
//执行事件
}
}
过渡动画
View移动动画
TranslateAnimation animation = new TranslateAnimation(
//View为原点
Animation.ABSOLUTE, 0f,//开始点的X坐标
Animation.ABSOLUTE, -400f,//移动到的X坐标
Animation.ABSOLUTE, 0f, //开始点的Y坐标
Animation.ABSOLUTE, 100f//移动到的Y坐标
);
animation.setDuration(2000);//动画的时间
animation.setFillAfter(true);//true为不回到原点 false反之
cy_img01.startAnimation(animation);
得到ip
private String getIp() {
WifiManager wm = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE);
if (!wm.isWifiEnabled())
wm.setWifiEnabled(true);
WifiInfo wi = wm.getConnectionInfo();
int ipAdd = wi.getIpAddress();
String ip = intToIp(ipAdd);
return ip;
}
private String intToIp(int i) {
return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF) + "." + (i >> 24 & 0xFF);
}
判断网络连接
判断方法
public boolean isNetworkConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
}
}
return false;
}
判断并弹到设置
if (isNetworkConnected(this))
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("网络信息提示")
.setMessage("当前网络不可用,请先进行网络设置")
.create();
builder.setPositiveButton("设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
startActivity(intent);
}
});
}
中英文切换
String[] a = new String[]{
"简体中文",
"English"
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setSingleChoiceItems(a,0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
wh = which;
}
}).setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
resources = getResources();// 获得res资源对象
config = resources.getConfiguration();// 获得设置对象
dm = resources.getDisplayMetrics();
switch (wh) {
case 0:
config.locale = Locale.SIMPLIFIED_CHINESE;
resources.updateConfiguration(config, dm);
onCreate(null);
break;
case 1:
config.locale = Locale.US;
resources.updateConfiguration(config, dm);
onCreate(null);
break;
}
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).create().show();
资源管理
Anim/ 创建
res(右击)->new->android resource file(点击)
【File name】 这里需要输入你想创建的动画文件名
【Resource type】这里需要修改成动画资源文件类型,
Directory name】这个地方需要修改成anim
HashMap排序
集合排序
HashMap<Integer, Integer> map = new HashMap<>();
map.put("d", 2);
map.put("c", 1);
map.put("b", 1);
map.put("a", 3);
List<Map.Entry<Integer,Integer>> list = new ArrayList<>(map.entrySet());
//排序
Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
@Override
public int compare(Map.Entry<Integer, Integer> t2, Map.Entry<Integer, Integer> t1) {
//return t2.getValue() - t1.getValue(); //integer类型排序
return t2.compareTo(t1); //string类型 排序
}
});
遍历
for(Map.Entry<Integer, Integer> a:list){
System.out.println(a.getKey());
System.out.println(a.getValue());
}
HTTP类 与 获取数据方法–网络框架
在项目清单文件中添加
android:usesCleartextTraffic="true"
HTTP类
public class HTTP {
private static RequestQueue requestQueue;
public static interface Lis {
void success(JSONObject json);
void error(String error);
}
public static void conn(Context context, String address, final JSONObject json, final Lis lis) {
if (requestQueue == null) {
Volley.newRequestQueue(context);
}
String url = "";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, json, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
lis.success(jsonObject);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
lis.error(volleyError.toString());
}
});
requestQueue.add(request);
}
}
获取数据方法
private void getdata(String user) {
try {
HTTP.conn(getContext(), "", new JSONObject().put("UserName", user), new HTTP.Lis() {
@Override
public void success(JSONObject json) {
try {
//普通获取
String result=json.getString("result");
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void error(String error) {
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
JSONArray 转数值的方法
private void getdata(String user) {
try {
HTTP.conn(getContext(), "", new JSONObject().put("UserName", user), new HTTP.Lis() {
@Override
public void success(JSONObject json) {
try {
//普通获取
String result=json.getString("result");
//转JSONArray
JSONArray array=json.getJSONArray("Array");
List ResultList=new ArrayList();
for (int i=0;i<array.length();i++){
JSONObject jsonObject=array.getJSONObject(i);
ResultList.add(jsonObject.getString("result"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void error(String error) {
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
GreenDao Application类 和 数据库管理类–数据库框架(保险起见 原始数据库需要看一下)
添加依赖
Project build.gradle:
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
app build.gradle:
apply plugin: 'org.greenrobot.greendao'
greendao {
//数据库的schema版本,也可以理解为数据库版本号
schemaVersion 1
//设置DaoMaster、DaoSession、Dao包名,也就是要放置这些类的包的全路径。
daoPackage 'com.example.thtf.kj.dao'
//设置DaoMaster、DaoSession、Dao目录
targetGenDir 'src/main/java'
}
implementation 'org.greenrobot:greendao:3.2.2'
实体类
建entity包放实体类
@Entity
public class Car {
@Id(autoincrement = true)
Long id;
String brand;
int money;
}
Ctrl+F9后
@Entity
public class Car {
@Id(autoincrement = true)
Long id;
String brand;
int money;
@Generated(hash = 840096487)
public Car(Long id, String brand, int money) {
this.id = id;
this.brand = brand;
this.money = money;
}
@Generated(hash = 625572433)
public Car() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getBrand() {
return this.brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getMoney() {
return this.money;
}
public void setMoney(int money) {
this.money = money;
}
}
并多出三个类
项目结构
编写MyApplication类
public class MyApplication extends Application {
private static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
GreenDaoManager.getInstance();
}
public static Context getContext() {
return mContext;
}
}
在项目清单文件中添加
android:name=".MyApplication"
注册MyApplication
编写GreenDaoManager数据库管理类
public class GreenDaoManager {
private static GreenDaoManager mInstance;
private DaoMaster mDaoMaster;
private DaoSession mDaoSession;
public GreenDaoManager() {
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(MyApplication.getContext(), "car-db", null);
DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
mDaoSession = daoMaster.newSession();
}
public static GreenDaoManager getInstance() {
if (mInstance == null) {
mInstance = new GreenDaoManager();
}
return mInstance;
}
public DaoMaster getDaoMaster() {
return mDaoMaster;
}
public DaoSession getDaoSession() {
return mDaoSession;
}
public DaoSession getNewDaoSession() {
mDaoSession = mDaoMaster.newSession();
return mDaoSession;
}
}
大功告成
AlertDialog AlertDialog.Builder–弹出框
默认弹出框
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("这是弹出框")
.setMessage("这是内容")
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(), which + "", Toast.LENGTH_SHORT).show();
}
}).setNeutralButton("忽略", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(), which + "", Toast.LENGTH_SHORT).show();
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(), which + "", Toast.LENGTH_SHORT).show();
}
}).create().show();
单选弹出框
1
final String[] a = new String[]{
"C",
"D",
};
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setSingleChoiceItems(a, 1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(), a[which] + "", Toast.LENGTH_SHORT).show();
}
}).show();
2
final String[] a = new String[]{
"A",
"B",
};
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setItems(a, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(), a[which] + "", Toast.LENGTH_SHORT).show();
}
}).show();
多选弹出框
final String[] dessert = new String[]{"抹茶千层", "芒果拿破仑", "草莓雪媚娘", "蓝莓慕斯"};
boolean[] begin = new boolean[]{false, false, false, false};
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext());
alertDialog.setMultiChoiceItems(dessert, begin, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
Toast.makeText(getContext(), dessert[which], Toast.LENGTH_SHORT).show();
}
}).setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(), "真好吃!", Toast.LENGTH_SHORT).show();
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(), "真不好玩!", Toast.LENGTH_SHORT).show();
}
}).show();
ViewPage 的监听 Fragment–碎片以及小圆点
布局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:background="#f1f1f1"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="100dp" />
<LinearLayout
android:id="@+id/ll"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:orientation="horizontal">
<TextView
android:id="@+id/t1"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/xld" />
<TextView
android:id="@+id/t2"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/xbd" />
<TextView
android:id="@+id/t3"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/xbd" />
</LinearLayout>
</RelativeLayout>
Fragment适配器
public class adapter extends FragmentPagerAdapter {
ArrayList<Fragment> fragments;
public adapter(FragmentManager fm, ArrayList<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
加入Fragment
ArrayList<Fragment> fragments = new ArrayList<>();
fragments.add(new page1());
fragments.add(new page2());
fragments.add(new page3());
vp.setAdapter(new adapter(getFragmentManager(), fragments));
滑动viewpage小圆点变化
vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
for (int i = 0; i < ll.getChildCount(); i++) {
if (i == position) {
ll.getChildAt(i).setBackgroundResource(R.drawable.xld);
} else {
ll.getChildAt(i).setBackgroundResource(R.drawable.xbd);
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
点击小圆点Fragment viewpage发生变化
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.t1:
vp.setCurrentItem(0);
break;
case R.id.t2:
vp.setCurrentItem(1);
break;
case R.id.t3:
vp.setCurrentItem(2);
break;
}
}
TableLayout–表格布局与传数据进表格
Xml
<TableLayout
android:id="@+id/tablelayout"
android:layout_width="708dp"
android:layout_height="wrap_content"
android:layout_marginLeft="100dp"
android:layout_marginTop="50dp"
android:stretchColumns="0,1,2,3" //每一格内容在一行中均匀分布
>
<TableRow>
<TextView
android:background="@drawable/black_kuang"
android:gravity="center"
android:text="学号"
android:textSize="30sp" />
<TextView
android:background="@drawable/black_kuang"
android:gravity="center"
android:text="姓名"
android:textSize="30sp" />
<TextView
android:background="@drawable/black_kuang"
android:gravity="center"
android:text="性别"
android:textSize="30sp" />
<TextView
android:background="@drawable/black_kuang"
android:gravity="center"
android:text="年龄"
android:textSize="30sp" />
</TableRow>
</TableLayout>
传数据进表
private TableLayout tablelayout = (TableLayout) view.findViewById(R.id.tablelayout);
TableRow row;
for(int n = 0; n < 5;n++){ //行数
ArrayList arrayList = new ArrayList();
arrayList.add(n);
arrayList.add("张"+n);
arrayList.add((int)(Math.random()*100)%2 == 0 ? "男":"女");
arrayList.add((int)(Math.random()*30)) ;
row = new TableRow(getContext());
for(int m = 0;m < arrayList.size();m++){
TextView textView = new TextView(getContext());
textView.setText(arrayList.get(m)+"");
textView.setGravity(Gravity.CENTER);
textView.setBackgroundResource(R.drawable.black_kuang);
row.addView(textView); //添加一行中的一格
}
tablelayout.addView(row);//添加一行
}
Handler Runnable–线程与更新UI
主体代码
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int what = msg.what;
switch (what) {
case 0:
//更新UI
break;
}
}
};
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
//想要做的事
mHandler.sendEmptyMessage(0);
}
};
开启线程
new Thread(mRunnable).start();
关闭线程
mHandler.removeCallbacks(mRunnable);
SimpleDateFormat–获得本地时间 年月日时分秒星期的格式
主体代码
//规定格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd天 HH:mm:ss E");
//获取本地时间
Date date = new Date(System.currentTimeMillis());
//显示时间
simpleDateFormat.format(date);
SharedPreferences.Editor–写入本地
Object o = getSharedPreferences("data", 0).edit();
((SharedPreferences.Editor) o).putString("a", "a");
((SharedPreferences.Editor) o).commit();
getSharedPreferences()–获取本地缓存
Object o = getSharedPreferences("data", 0);
((SharedPreferences) o).getString("a", "");
VideoView MediaController --视频组件与进度条组件的搭配
MediaController mediaController = new MediaController(getContext());
vd.setVideoURI(Uri.parse("android.resource://" + getContext().getPackageName() + "/" + R.raw.v1));
vd.setMediaController(mediaController);
setVideoURI();导入视频
start()播放
pause()暂停
获取网页代码路径 与视频文件路径
网页代码路径
1. 新建assets目录
2. 在assets目录中创建web(名字可以自己起)文件夹(据说如果不创建这层目录就无法拿到assets中的文件)
webView.loadUrl("file:///android_asset/web/2.html");
视频文件路径
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/raw/" + R.raw.test_video);
mVideoView.setVideoURI(uri);
LayoutParams --设置View的大小
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(160, 160);
Spinner --下拉框的适配和监听
适配
final String[] strings = new String[]{
"A", "B", "C", "D"
};
ArrayAdapter<String> adapter=new ArrayAdapter<String>(getContext(),android.R.layout.simple_expandable_list_item_1,strings);
sp.setAdapter(adapter);
监听
sp.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.e("", ":"+strings[position] );
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Switch --开关的适配和监听
xml文件
<Switch
android:id="@+id/sw"
android:textOn="开"
android:textOff="关"
android:layout_width="wrap_content"
android:layout_height="wrap_content
<!--原点背景-->
android:thumb="@drawable/b1"
<!--背景颜色-->
android:track="@drawable/b2" />
监听
sw.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//isChecked 为开关
}
});
ExtendableListView --列表视图的适配
Xml
<ExpandableListView
android:id="@+id/expandable_list_view_id"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ExpandableListView>
父视图group_item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#cccccc"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_group"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:gravity="center"
android:text="group text"
android:textColor="#000000"
/>
</LinearLayout>
子视图 child_item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_child"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/tv_child"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="item text"
android:textColor="#000000"/>
</LinearLayout>
适配器
//为ExpandableListView自定义适配器
class MyExpandableListView extends BaseExpandableListAdapter {
//返回一级列表的个数
@Override
public int getGroupCount() {
return groups.length;
}
//返回每个二级列表的个数
@Override
public int getChildrenCount(int groupPosition) { //参数groupPosition表示第几个一级列表
Log.d("smyhvae", "-->" + groupPosition);
return childs[groupPosition].length;
}
//返回一级列表的单个item(返回的是对象)
@Override
public Object getGroup(int groupPosition) {
return groups[groupPosition];
}
//返回二级列表中的单个item(返回的是对象)
@Override
public Object getChild(int groupPosition, int childPosition) {
return childs[groupPosition][childPosition]; //不要误写成groups[groupPosition][childPosition]
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
//每个item的id是否是固定?一般为true
@Override
public boolean hasStableIds() {
return true;
}
//【重要】填充一级列表
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.group_item, null);
} else {
}
TextView tv_group = (TextView) convertView.findViewById(R.id.tv_group);
tv_group.setText(groups[groupPosition]);
return convertView;
}
//【重要】填充二级列表
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.child_item, null);
}
ImageView iv_child = (ImageView) convertView.findViewById(R.id.iv_child);
TextView tv_child = (TextView) convertView.findViewById(R.id.tv_child);
//iv_child.setImageResource(resId);
tv_child.setText(childs[groupPosition][childPosition]);
return convertView;
}
//二级列表中的item是否能够被选中?可以改为true
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
适配
//Model:定义的数据
private String[] groups = {"A", "B", "C"};
//注意,字符数组不要写成{{"A1,A2,A3,A4"}, {"B1,B2,B3,B4,B5"}, {"C1,C2,C3,C4"}}
private String[][] childs = {{"A1", "A2", "A3", "A4"}, {"A1", "A2", "A3", "B4"}, {"A1", "A2", "A3", "C4"}};
expandable_list_view_id.setAdapter(new MyExpandableListView());
监听
//父监听
expandable_list_view_id.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
Toast.makeText(getContext(),groups[groupPosition],Toast.LENGTH_SHORT).show();
return false;
}
});
//子监听
expandable_list_view_id.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Toast.makeText(getContext(),childs[groupPosition][childPosition],Toast.LENGTH_SHORT).show();
return false;
}
});
Timer-TimerTask定时器
1. 隔几秒运行一次
Int i=1;
Timer timer=new Timer();
TimerTask timerTask=new TimerTask() {
@Override
public void run() {
Log.e("a", "run: "+i++ );
}
};
timer.schedule(timerTask,1000);
1.timer.schedule(task, time); // time为Date类型:在指定时间执行一次。
2.timer.schedule(task, firstTime, period); // firstTime为Date类型,period为long。从firstTime时刻开始,每隔period毫秒执行一次。
3.timer.schedule(task, delay) // delay 为long类型:从现在起过delay毫秒执行一次
4.timer.schedule(task, delay, period) // delay为long,period为long:从现在起过delay毫秒以后,每隔period。毫秒执行一次。
timer.schedule(timerTask,1000,100);
Handler定时器
mHandler.postDelayed(mRunnable,1000);
NotificationManager Notification–通知栏的使用
通知栏的方法
private void notice(Context context, String title, String content, int icon, int i) {
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("1", "11", NotificationManager.IMPORTANCE_LOW);
manager.createNotificationChannel(channel);
Notification notification = new Notification.Builder(context, "1")
.setContentTitle(title)
.setContentText(content)
.setSmallIcon(icon)
.build();
manager.notify(i, notification);
} else {
Notification.Builder notification = new Notification.Builder(context)
.setContentTitle(title)
.setContentText(content)
.setSmallIcon(icon);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
manager.notify(i, notification.build());
}
}
}
shape --简单的图形框绘画
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="40dp"
android:height="40dp" />
<stroke
android:width="1dp"
android:color="#000000" />
<corners android:radius="20dp" />
<gradient
android:endColor="#eeeeee"
android:startColor="#eeeeee" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="40dp"
android:height="40dp" />
<stroke
android:width="1dp"
android:color="#000000" />
<corners android:radius="20dp" />
<gradient
android:endColor="#00FF0A"
android:startColor="#00FF0A" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="40dp" />
<corners android:radius="20dp" />
<gradient
android:endColor="#00FF0A"
android:startColor="#00FF0A" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="40dp" />
<corners android:radius="20dp" />
<gradient
android:endColor="#BBBBBB"
android:startColor="#BBBBBB" />
</shape>
CalendarView --日历控件 监听
Xml
<CalendarView
android:id="@+id/Cal"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
监听
Cal.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(@NonNull CalendarView view, int year, int month, int dayOfMonth) {
String str=year+"年"+month+"月"+dayOfMonth+"日";
Toast.makeText(getContext(),str+"",Toast.LENGTH_SHORT).show();
}
});
include ViewStub --包含视图和延时包含视图的使用
include
<include layout="@layout/activity_login" />
ViewStub
Xml
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="main" />
<ViewStub
android:layout_below="@+id/textView2"
android:id="@+id/viewstub"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/itflight">
</ViewStub>
<Button
android:id="@+id/buttonstub"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加载ViewStub" />
延时加载
View view = (View) findViewById(R.id.viewstub);
if (view != null) {
view.setVisibility(View.VISIBLE);
} else {
setTitle("加载子窗口");
}
组件显示与隐藏
显示
view.setVisibility(View.VISIBLE);
隐藏
view.setVisibility(View.GONE);
导入包的方法
App- libs添加包
右击 add library
Fragment中使用getFragmentManager()嵌入布局 在activity中
getSupportFragmentManager().beginTransaction().replace(R.id.maincontent,new Fragment_2()).commit();
//R.id.maincontent 为需要嵌入的布局id
// new Fragment_2() 为Fragment
SimpleAdapter ArrayAdapter 的使用
ArrayAdapter
String[] a = new String[]{
"A", "B"
};
ArrayAdapter<String> stringArrayAdapter=new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,a);
SimpleAdapter
final String[] actionTexts = new String[]{
getString(R.string.g1),
getString(R.string.g2),
getString(R.string.g3),
getString(R.string.g4),
getString(R.string.g5),
getString(R.string.g6),
getString(R.string.g7),
getString(R.string.g8),
getString(R.string.g9),
getString(R.string.g10),
getString(R.string.res_left_chuanyi),
getString(R.string.res_left_exit)
};
int[] actionImages = new int[]{
R.drawable.btn_l_star,
R.drawable.btn_l_book,
R.drawable.btn_l_arrows,
R.drawable.btn_l_grid,
R.drawable.btn_l_speech_3,
R.drawable.btn_l_twitter,
R.drawable.btn_l_skype,
R.drawable.btn_l_windows,
R.drawable.btn_l_slideshow,
R.drawable.btn_l_suitcase,
R.drawable.btn_l_target,
R.drawable.btn_l_download
};
actionItems = new ArrayList<HashMap<String, Object>>();
actionAdapter = new SimpleAdapter(getApplicationContext(), actionItems, R.layout.left_list_fragment_item,
new String[]{"action_icon", "action_name"},
new int[]{R.id.recharge_method_icon, R.id.recharge_method_name});
for (int i = 0; i < actionImages.length; ++i) {
HashMap<String, Object> item1 = new HashMap<String, Object>();
item1.put("action_icon", actionImages[i]);
item1.put("action_name", actionTexts[i]);
actionItems.add(item1);
}
listView.setAdapter(actionAdapter);
ProgressBar的使用
Xml
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="898dp"
android:layout_height="41dp" />
Style
默认圆形
?android:attr/progressBarStyleHorizontal" 条状
属性
progress.setMax(1000); //设置最大值
progress.setProgress(100); //设置第一值
progress.setSecondaryProgress(500);//设置第二值
退出程序
finish();
等等
配张图自己感受
面试题部分
<meta charset="utf-8">
阿里Android面试题集(含答案解析):
第一章计算机基础面试题
-
第一节、网络面试题
-
第二节、操作系统面试题
-
第三节、数据库面试题
第二章 数据结构和算法面试题
- 数据结构与算法
第三章Java面试题
-
第一节Java基础面试题
-
第二节 Java并发面试题
-
第三节Java虚拟机面试题
第四章 Android面试题
- 第一节 Android基础面试题
- 第二节Android高级面试题
第五章 其他扩展面试题
-
Kotlin
-
大前端
-
脚本语言
第六章 非技术面试题
-
高频题集
-
次高频题集
每个问题我们都尽量附上1个标准参考答案,都是我们反复摸索消化(真心花了很多时间),觉得写的比较好的文章作为答案。这样就可以节省大家自己去搜索的时间,把时间用在正确的东西上。
其实我们也可以直接以简易的、群友分享的答案写出来,但是这并帮助不了同学们去深刻理解,三思之下还是采用标准答案作为参考。不明白或者想通俗了解的,可以点击我加入我们BAT技术群一起交流讨论。下面是我们每章知识点的概述:
第一章 计算机基础面试题
阿里面试也会考察计算机基础,主要考察我们是否系统的学习了操作系统和计算机组成原理,因为只有我们看完操作系统后才能系统的认识计算机的原理。
第二章 数据结构和算法面试题
对于算法面试准备,无疑就是刷《剑指Offer》+ LeetCode 效果最佳。刷《剑指Offer》是为了建立全面的算法面试思维,打下坚实的基础,刷LeetCode则是为了不断强化与开阔我们自己的算法思想。这两块 CS-Notes 中已经实现地很完美了,建议大家将《剑指Offer》刷完,然后再至少刷100道LeetCode题目以上。
第三章 Java面试题
Java 是 Android App 开发默认的语言, Android Framework 也是默认使用 Java 语言,熟练掌握 Java 语言是 Android 开发者的必备技能。当然也是我们字节跳动青睐的考题选择方向!
第四章 Android面试题
Android面试分为基础面试题+高级面试题两个部分。其中高级面试题部分的性能优化、Framework、三方源码属于我们考察的重点、难点方向!
第五章、第六章 其他扩展面试题+非技术面试题
面试重点;项目中web的交互
阿里巴巴Android面试题集
简历制作+春招困惑解答+经典HR面试解析
以上是我们整理总结的阿里巴巴Android面试历年真题解析,希望对大家有帮助;同时我们经常也会遇到很多关于简历制作,职业困惑、HR经典面试问题回答等有关面试的问题。同样的我们搜集整理了全套简历制作、春招困惑、HR面试等问题解析参考建议。
网友评论