入门
单选题
下列选项中,属于定义字符串资源使用的标签的是()A
A、< string/ >
B、< strings/ >
C、< include/ >
D、demin
在Activity的onCreate()方法中,加载布局资源文件的方法是()B
A、setTheme()
B、setContentView()
C、setView()
D、setGroupView()
下面关于尺寸资源的描述,正确的是()A
A、尺寸资源通常定义在res/values/dimens.xml文件中
B、尺寸资源只能在XML文件中调用
C、尺寸资源的单位只能使用dp表示
D、在Android Studio3.2版本中,默认创建了dimens.xml文件。
下面关于LogCat的描述,正确的是()A
A、Android使用android.util.Log类的静态方法实现输出程序的调试信息
B、LogCat区域中日志信息显示的颜色是一致的
C、Warning级别的日志显示的是调试的信息
D、error级别的日志显示的是断言失败后的错误消息
解析:
B中LogCat区域中日志信息根据日志级别的不同显示不同的颜色
C中Warning级别的日志是警告信息
D中error级别的日志显示的是错误信息,断言失败后的错误消息是assert
下列选项中,属于Log类中显示黑色的日志内容的方法的是()A
A、Log.v()
B、Log.e()
C、Log.wtf()
D、Log.w()
解析:
级别 | 显示信息 | 日志信息颜色 |
---|---|---|
verbose(V) | 全部信息 | 黑色 |
debug(D) | 调试信息 | 蓝色 |
info(I) | 一般信息 | 绿色 |
warning(W) | 警告信息 | 橙色 |
error(E) | 错误信息 | 红色 |
assert | 断言失败后的错误消息 | 红色 |
判断题
- px是一种与屏幕密度无关的尺寸单位。(×)
解析:
每个px(pixels,像素)对应屏幕上的一个点,是与屏幕密度有关的尺寸单位;而dp/dip(Density-independent Pixels,设备独立像素)是一种与屏幕密度无关的尺寸单位。
填空题
- AndroidManifest.xml是整个程序的配置文件,在该文件中配置程序所需【】和注册程序中用到的四大组件。
答案:权限
简答题
简述Android源代码的编译过程
答:Java源文件经过JDK编译器编译为class文件后,Dalvik虚拟机中的Dx工具会将部分class文件转换成dex文件、dex文件还会在Dalvik虚拟机中进一一步优化成odex文件。
简述Android系统架构包含的层次以及各层的特点
答: Android 系统架构从高到低分为四层,分别为依次是应用程序层(Applications) 、应用程序框架层( Application Framework)、核心类库(Libraries) 和Linux内核( Linux Kernel)。
各层的特点具体如下:
应用程序层:一个核心应用程序的集合,安装在手机中的应用程序都属于这一层;
应用程序架构层:主要提供了构建应用程序时用到的各种API,例如活动管理器(ActivityManager);
核心类库:主要包含 了系统库和Android运行环境;
Linux内核:他为Android设备的各种硬件提供了底层的驱动,如:显示驱动。
控件 & 布局
单选题
下列选项中,属于CheckBox控件设置选择监听事件的方法的是()C
- A、setOnClickListener
- B、setOnCheckedListener
- C、setOnCheckedChangeListener
- D、setOnMenuItemSelectedListener
下面关于ListView的描述,错误的是()D
- A、ListView以列表的形式展示数据内容
- B、ListView的条目之间显示分割线
- C、ListView能够根据列表的高度自适应屏幕显示
- D、ListView必须实现滚动条的显示,才能实现滑动功能
解析:通过设置android:scrollbars来决定是否显示滚动条
下列选项中,属于设置线性布局内控件排列顺序的属性的是()A
- A、android:orientation
- B、android:layout_weight
- C、android:layout_centerVertical
- D、android:layout_centerHorizontal
下列选项中,用于EditText控件中内容为空时显示提示文本信息的属性为()A
- A、android:hint
- B、android:tint
- C、android:password
- D、android:textColorHint
解析:hint意为“暗示”,用于EditView;而tint意为“着色”,用于ImageView
多选题
下列选项中,属于RecyclerView适配器的方法的是()AC
- A、onCreateViewHolder()
- B、getView()
- C、onBindViewHolder()
- D、getCount()
判断题
- AlertDialog可以通过new关键字创建对象。(×)
解析:调用AlertDialog.Builder的create()方法创建AlertDialog对象
- AlertDialog对象是调用AlertDialog.Builder的create()方法创建的。(√)
解析:调用AlertDialog的静态内部类Builder创建AlertDialog.Builder的对象
简答题
请说明一下布局有哪几种类型,作用分别是什么(或者说特点)
- RelativeLayout相对布局:相对于其他控件或者容器决定该布局内子控件的位置
- LinearLayout线性布局:使控件以竖直或者水平方向排列(android:orientation指定)
- TableLayout表格布局:使控件以表格形式排列,采用行、列管理,搭配TableRow使用,TableRow代表一行,往里面添加的控件代表一列
- GirdLayout网格布局:能使控件交错显示,能够避免因布局嵌套对设备性能的影响,更利于自由布局的开发
- FrameLayout帧布局:使控件按照创建顺序在屏幕上重叠显示,后加入的在上面,默认在左上角对齐(eg.刮刮乐)
- AbsoluteLayout绝对布局:通过绝对的坐标控制控件摆放的位置
- ConstraintLayout约束布局:适合于可视化的方式编写界面布局(可视化操作的背后仍是XML实现,不过是Android Studio根据我们的操作自动生成)
简述优化ListView加载数据的方法
- 创建ViewHolder类,在该类中声明需要加载的控件
- 复用convertView对象从而减少Item对象的创建
- 使用getTag()和setTag()的方法关联convertView对象和ViewHolder对象
解析:
在加载Item布局时,会使用findViewById()方法找到Item布局中的各个控件,在每一次加载新的Item数据时都会进行控件寻找,这样也会产生耗时操作。
为了优化ListView减少耗时操作,可以将要加载的子View放在ViewHolder类中,当第一次创建convertView时将这些控件找出,在第二次重用convertView时就可直接通过convertView中的getTag()方法获得这些控件。
下面贴一段我在实际开发中的代码:
public class NewsAdapter extends BaseAdapter {
private List<News> newsList;
private Context context;
public NewsAdapter(Context context, List<News> objects) {
this.context = context;
this.newsList = objects;
}
@Override
public int getCount() {
return newsList != null ? newsList.size() : 0;
}
@Override
public Object getItem(int position) {
return newsList.get(position);
}
@Override
public long getItemId(int position) {
// 没实现
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.news_item, null);
holder.newsImage = convertView.findViewById(R.id.news_image);
holder.newsTitle = convertView.findViewById(R.id.news_title);
holder.newsTime = convertView.findViewById(R.id.news_time);
holder.newsSource = convertView.findViewById(R.id.news_source);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
News news = newsList.get(position);
Glide.with(context).load(news.getCoverPic()).into(holder.newsImage);
holder.newsTitle.setText(news.getTitle());
holder.newsTime.setText(news.getPubDate());
holder.newsSource.setText(news.getSource());
return convertView;
}
class ViewHolder {
ImageView newsImage;
TextView newsTitle;
TextView newsTime;
TextView newsSource;
}
}
与ListView相比,RecyclerView的优势在哪。(简述ListView与RecyclerView的区别)
展示效果:RecyclerView控件可以通过LayoutManager类实现横向或竖向的列表效果、瀑布流效果和GridView效果,而ListView控件只能实现竖直的列表效果。
适配器:RecyclerView控件使用的是RecyclerView.Adapter适配器,该适配器将BaseAdapter中的getView()方法拆分为onCreateViewHolder()方法和onBindViewHolder()方法,强制使用ViewHolder类,使代码编写规范化,避免了初学者写的代码性能不佳。
复用效果:RecyclerView控件复用Item对象的工作由该控件自己实现,而ListView控件复用Item对象的工作需要开发者通过convertView的setTag()方法和getTag()方法进行操作。
动画效果:RecyclerView控件可以通过setItemAnimator()方法为Item添加动画效果,而ListView控件不可以通过该方法为Item添加动画效果。
还有一个我不知道算不算,RecyclerView要在gradle中导入外部依赖
implementation 'androidx.recyclerview:recyclerview:1.1.0'
下面还是贴一段我在实际开发中使用RecyclerView的代码:
public class RvAdapter extends RecyclerView.Adapter<RvAdapter.MyViewHolder> {
private List<Course> courseList;
private Context context;
public RvAdapter(List<Course> courseList, Context context) {
this.courseList = courseList;
this.context = context;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = View.inflate(context,R.layout.course_item,null);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.title.setText(courseList.get(position).getTitle());
holder.subTitle.setText(courseList.get(position).getSubTitle());
int color = R.color.colorAccent;
switch (position % 4) {
case 0:
color = R.color.lesson_0;
break;
case 1:
color = R.color.lesson_1;
break;
case 2:
color = R.color.lesson_2;
break;
case 3:
color = R.color.lesson_3;
break;
}
holder.number.setBackgroundResource(color);
holder.number.setText(Integer.toString(position+1));
}
@Override
public int getItemCount() {
return courseList == null ? 0 : courseList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView title;
private TextView subTitle;
private TextView number;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.my_title);
subTitle = itemView.findViewById(R.id.sub_title);
number = itemView.findViewById(R.id.number);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(myItemClickedListener != null) {
myItemClickedListener.OnClicked(getAdapterPosition());
}
}
});
}
}
private OnRecyclerItemClickedListener myItemClickedListener;
public void setMyItemClickedListener(OnRecyclerItemClickedListener listener) {
myItemClickedListener = listener;
}
public interface OnRecyclerItemClickedListener {
void OnClicked(int position);
}
}
简述实现Button按钮的点击事件的方式有哪几种
(1)匿名内部类:
new 一个
OnClickListener
接口作为Button
的setOnClickListener
方法的参数
public class MainActivity extends AppCompatActivity {
Button btn1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button)findViewById(R.id.btn1);
// 给Button添加点击事件的第一种方式:匿名内部类
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,Example1.class);
startActivity(intent);
}
});
}
(2)内部类:
在
Button
所在的class
内部再建一个类ClickListener
并实现OnClickListener
接口。
直接new一个ClickListener
的实例作为Button
的setOnClickListener
方法的参数
public class MainActivity extends AppCompatActivity {
Button btn1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button)findViewById(R.id.btn1);
// 给Button添加点击事件的第二种方式:内部类
btn1.setOnClickListener(new ClickListener());
}
class ClickListener implements View.OnClickListener {
@Override
public void onClick(View view) {
Log.i("Info","btn1 goto next page");
Intent intent = new Intent(MainActivity.this,Example3.class);
startActivity(intent);
}
}
}
(3)实现OnClickListener
接口
Button
所在的class
本身实现OnClickListener
接口,并且作为Button
的setOnClickListener
方法的参数
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
Button btn1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button)findViewById(R.id.btn1);
btn1.setOnClickListener(this);
}
// 给Button添加点击事件的第三种方式:实现OnClickListener接口
@Override
public void onClick(View view) {
Log.i("Info","btn1 goto next page");
Intent intent = new Intent(MainActivity.this,Example3.class);
startActivity(intent);
}
}
(4)直接在布局文件中指定点击事件
以上三种方式归根结底都是实现
OnClickListener
来监听Button
的点击事件,而下面的方式是直接在布局文件中直接指定响应Button
的点击事件的方法
xml代码
<Button android:id="@+id/btn4" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="指定点击事件" android:onClick="btn4Click" />
java代码
public class MainActivity extends AppCompatActivity {
Button btn1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// 给Button添加点击事件的第四种方式:直接在布局文件中指定点击事件
public void btn4Click(View view){
Log.d("DEBUG","btn1 go to next page");
Intent intent = new Intent(MainActivity.this,Example4.class);
startActivity(intent);
}
}