android项目常见疑问
有些描述的比较简单,不过如果你的项目真的遇到了这些问题,我相信瞄一眼也知道我记录的是什么问题,所以无需描述的太繁琐,这里不是讲知识,而是一个备忘录或者是某些问题的答案,这些问题你通常在第一次遇到时比较困惑。
1.Android Service的lifecycle感知事件,Service本来并没有Stop生命周期函数,只有Destroy生命周期函数。自定义类为何可以感知到Service的ON_STOP和ON_DESTROY两个事件?
答:通过查看Android官方源码得知 有一个ServiceLifecycleDispatcher在onServicePreSuperOnDestroy中纷发了 ON_STOP与ON_DESTROY两个事件,因此当Serivce执行到生命周期onDestroy函数时,我们的自定义类可以感知到Service的ON_STOP与ON_DESTROY两个事件。
2.多部件上传文件和文本
(1)创建多部件参数:文件部件参数。
步骤step1.创建文件requestBody方法:
方法1. RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
方法2:创建文件requestBody时,同时指定该文件的MediaType为图片image*
RequestBody requestFile = RequestBody.create(MediaType.parse("image*//*"), file); //创建文件requestBody
方法3:不指定文件类型,由服务器接收程序去分析文件类型为图片还是音视频
RequestBody requestFile = RequestBody.create(MediaType.parse(""), file);
其中create函数的第一个参数MediaType,可以向上面那样写死,也可以使用下面这个方法获取:
/**
* @param path: 文件的本地路径,如SD卡下面的一个文件
*/
public static MediaType guessMimeType(String path) {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String contentType = fileNameMap.getContentTypeFor(path);
if (contentType == null) {
contentType = "application/octet-stream";
}
return MediaType.parse(contentType);
}
步骤2. 构造文件part
//文件
MultipartBody.Part filePart = MultipartBody.Part.createFormData("fileKey", file.getName(), requestFile);
(2)Retrofit调用服务器接口 ,上传文件、文本
@Multipart
@Headers({"CONNECT_TIMEOUT:600000", "READ_TIMEOUT:600000", "WRITE_TIMEOUT:600000"})
@POST("utils/uploadFile")
Observable<BaseEntity<String>> postFile(
@Part MultipartBody.Part fileParams, @Query("type") String type
);
3. 去掉BottomNavigationView长按提示Toast
答:建议使用BottomNavigationBar。BottomNavigationView切换速度太慢。
4. 集成百度地图so库时,经常初始化不了so库,
答:解决办法1. 在app模块下的build.grale里添加
sourceSets {
main {
jniLibs.srcDir 'libs'
}
}
解决办法2:如果上述解决不了,请观察您是否还引用了极光等其它第三方so库,百度要和极光so库的 CPU架构文件夹一致,极光CPU架构文件夹不能比百度多,名字要一样,如armeabi.
5. android studio Cannot recover key,再怎么用签名文件打包都提示失败。
答:重新输入keystore的密码,不要使用记忆的密码。
6. 去掉tablayout水波纹效果
答:配置两个tabLayout属性为透明
app:tabBackground="@android:color/transparent"
app:tabRippleColor="@android:color/transparent"
7. 自定义tablayout中的tab标签布局:
public void defineTabTitle(){
for (int tabIndex = 0; tabIndex < mDataBinding.tablayout.getTabCount(); tabIndex++) {
TabLayout.Tab tab = tablayout.getTabAt(tabIndex);
View view = View.inflate(getActivity(), R.layout.bottom_navigation, null);
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
switch (tabIndex){
case 0:
tv_name.setText(R.string.new_order);
break;
case 1:
tv_name.setText(R.string.new_task);
break;
case 2:
tv_name.setText(R.string.has_complete);
break;
case 3:
tv_name.setText(R.string.has_forward);
break;
}
tab.setCustomView(view);
//tab.setIcon(icon)
}
}
8 textview实现省略号
android:singleLine="true"
android:ellipsize="end"
当空间不足时自动省略文字,用...代替。无需设置android:maxems,如果设置了android:maxems,反倒不能充分利用 剩余空间,还是最好让系统自动判断空间是否不足,发现不足了才省略文字。
9.实现跑马灯效果textview
android:scrollHorizontally="true"
android:focusableInTouchMode="true"
android:focusable="true"
android:marqueeRepeatLimit="marquee_forever"
android:ellipsize="marquee"
android:singleLine="true"
android:layout_width="46dp"
10. linearlayout设置阴影属性无效
答:给linearlayout设置一个背景色,再设置阴影属性
android:elevation="4dp"
11 recyclerview与scrollview滑动冲突
答:将scrollview替换为Netscrollview
12 recyclerview抢夺焦点,每次切换到页面时,页面顶部总是优先显示列表。
答:给recyclerview的父容器布局添加以下两个属性:
android:focusable="true"
android:focusableInTouchMode="true"
13. viewPager崩溃:当缩放图片时
提示错误:java.lang.IllegalArgumentException: pointerIndex out of range pointerIndex=-1 pointerCount=1
答:重写onInterceptTouchEvent,捕获异常,这个是系统控件的BUG. 重写代码如下:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try{
return super.onInterceptTouchEvent(ev);
}catch (IllegalArgumentException e){
e.printStackTrace();
}
return false;
}
14. ERROR: Failed to resolve: com.github.PhilJay:MPAndroidChart:v3.1.0
答:修改项目级的build.gradle, 添加 maven { url 'https://jitpack.io' },具体配置如下:
allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
}
}
15. android正文字体大小一般是多少?
答: 正文字体大小一般为15sp,行高设置成23dp
16.让CheckBox响应面积扩大
解决方案:
设置为以下属性后,
android:button="@null"
android:drawableStart="@drawable/hide_pwd_image"
checkBox的android:padding才能生效。
然后设置android:padding的值来扩大CheckBox的面积。
xml设置如下:
<CheckBox
android:id="@+id/checkShowPwd"
android:visibility="visible"
android:drawableStart="@drawable/hide_pwd_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="@android:color/transparent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:button="@null"
android:checked="false" />
代码动态改变android:drawableStart
Drawable drawableOpenEye = getResources().getDrawable(R.drawable.open_eye);
mDataBinding.checkShowPwd.setCompoundDrawablesWithIntrinsicBounds( drawableOpenEye, null,null,null);
17.EvenBus接收不到事件
答:看接收函数的参数是否使用了基本类型。正确应该使用引用类型,例如int参数要改成Integer类型,才能接收到Event.getDefault().post()的事件。
18.carview阴影不明显
答:设置这两个属性:app:cardPreventCornerOverlap="true" app:cardUseCompatPadding="true"
19.android.os.FileUriExposedException: file:///xxxx exposed beyond app through Intent.getData()
解决方法
AndroidMainFest.xml里添加:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.port.district.comment"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
res下新建xml文件夹,新建xml文件file_paths.xml,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path path="." name="external_path" />
<external-path name="sdcard_root" path="."/>
</paths>
18.去掉按钮按下阴影
android:stateListAnimator="@null
19. 获取SHA1步骤:
1. 生成jks签名文件
2. 放在studio所用java环境的bin下
3. keytool -list -v -keystore my.jks
20. 修改BottomNavigationView的文字图片,让其都置灰
/**
* 初始化底部第1个菜单,刚开始要强行让其处于未选中状态(文字图片变灰),
* 因为默认BottomNavigationView会选中第1个
*/
@SuppressLint("RestrictedApi")
void initFirstBottomMenu(){
mPayAdvertMenu = mNavigation.getMenu().findItem(R.id.pay_advert);
mPayAdvertMenu.setIcon(R.drawable.kx_light); //让图片置灰色
//让文字置灰色
BottomNavigationMenuView menuPayAdvertView = (BottomNavigationMenuView) mNavigation.getChildAt(0);
int colorUnSelected = this.getResources().getColor(R.color.main_menu_text_unchecked);
ColorStateList colorStateList =
new ColorStateList(new int[][]{
{android.R.attr.state_selected}, {android.R.attr.state_enabled}},
new int[]{colorUnSelected,colorUnSelected});
menuPayAdvertView.setItemTextColor(colorStateList);
}
21. 为按钮添加水波纹效果
(1)创建drawable下的文件 ripple.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/tab_text_unselected">
<item android:drawable="@color/white"/>
</ripple>
(2) 在布局layout里设置button的background="@drawable/ripple"
22.All flavors must now belong to a named flavor dimension.
答:在app的build.gradle文件里的defaultconfig下添加如下:
flavorDimensions "versioncode"
23 recyclerview的grid网格形式的item内容无法居中
答:设置item的根布局为linearlayout,并设置layout_width="match_parent",然后再设置android:gravity="center"等属性
24. 代码设置textview的drawable
Drawable drawable = holder.itemView.getContext().getDrawable(homeFuncItem.drawableResId); // 这一步必须要做,否则不会显示. drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight()); homeFuncItemBinding.tvFuncName.setCompoundDrawables(null, drawable, null, null); homeFuncItemBinding.tvFuncName.setText(homeFuncItem.funcNameResId); //分类名称