Android 开发常见问题

1、AsyncTask串行和并行问题
2、支付宝调用界面,IP代理,调不起界面问题
3、git reset --hard 导致本地代码消失问题
4. textview inclueFontPadding问题
5. 支付宝授权问题

Android 的gradle中compile和provide的区别
  • compile是从repository(默认是jCenter())里下载一个依赖包进行编译并打包。
  • provide值提供编译支持,但是不会写入apk
  • compile files 是从本地libs目录下找寻jar包编译并打包。类似还有fileTree
  • compile project是将另一个module进行编译并打包

Viewpager 懒加载问题

通过ItemCycleControl来管理viewpager列表的声明周期,需要在viewpagerde setData之前调用,其主要通过实现Viewpager.OnPageChangeListener和View.OnAttachStateChangeListener接口

通过重写onPageScrolled方法,获取当前的position和positionoffset
并根据position是否为-1判断向左或者向右滑动,并通过将viewpager中的view实现ItemCycleListener接口,并通过监听对比某一view滑动前后的状态决定其调用onWillAppear或者onWillDisAppear或者已经显示或已经完全隐藏回调方法。当然最后在重写onViewDetachFromWindow中移除绑定监听和滑动监听

图片压缩与上传

图片压缩采用的是github上的Luban压缩工具,通过参考或者自创压缩规则推求极致
的压缩效果,目前的版本压缩效果主要参考微信。(因为微信用户大,容易被用户接受)

算法
该算法中比例是指:图片短边除以长边为该图片的比例
使用Retrofit + Rxjava 实现图片上传。图片压缩使用md5,serviceAPI使用@Url和@PartMap Map 再通过RequestPstFile统一设置MediaType–> new Object[]

git 看不到远程分支的问题

git branch -a 只能看到本地跟踪的远程分支的信息,如果想要看到新的分支需要先使用git fetch
git fetch 与 git pull的区别
在本地文件夹中隐藏文件.git的config文件中可以看到本地分支和远程关联的分支信息
同时其中的master文件保存的是本地库中最新的commit id,当然其中refs文件中的remote指的是本地跟踪的远程分支的commit id
使用git fetch时本地库的相关信息不会发生变化,只会更新远程的分支信息,使用git pull是将本地库和远程的库同步

Got IOException performing flipjava.io.IOException: write failed: EINVAL (Invalid argument)

在Android中创建文件名不能包含“:”冒号。

Android APK升级时有的手机可能会有安装包解析失败的问题

此时需要代码动态获取权限,通过Runtime.exec(“chmod 777 + path”)的方式获取权限

haroopad

Android studio V1 V2签名

V1:应该是通过ZIP条码进行验证,这样APK签署后可进行许多修改,可以移动甚至是重新压缩文件
V2:验证压缩文件的所有字节,而不是单个ZIP条目,因此在签名后无法再更改(包括zipalign)。正因如此,在编译过程中,我们将压缩、调整和签署合并成一部完成,好处显而易见,更安全而且新的签名看缩短在设备上进行验证的时间(不需要费时的解压缩然后验证),从而加快安装速度

使用
  • 只勾选V1签名并不会影响什么,只是在7.0上不会使用更安全的验证方式。
  • 只勾选V2签名7.0以下会出现安装完显示未安装,7.0以上则使用V2的方式验证。
    同时勾选都没有问题。

ArrayList.toArray(T[] a)的说明

这个方法就是将一个链表转换成数组
``

String[] desc = new String[list.size()];
list.toArray(desc);
output(desc);

``
如果初始化的数组不足以容纳list时,会产生一个新的数组,之前的desc不会变,还是为空。

RecyclerView的layoutManager

其中的setSpanSizeLookup可以让你根据position来设置span size。

Android 6.0动态申请权限

``

private boolean checkPermissions(){
	String[] permissions = new String[]{Manifest.permission.READ_PHONE_STATE,Manifest.permission.ACCESS_COARSE_LOATION}; 
	reture requestPermisssion(permissions);  
}

private static final int REQUEST_NETWORK_SETTING = 0;
private static final int REQUEST_CODE_ASK_PERMISSION = 1;

public boolean requestPermissions(String[] permissions) {
	List required = new ArrayList<>(permissions.length);
	for(String permission : permissions){
		if(ContextCompat.checkSelfPermission(this,permission) != PackageManager.PERMISSION_GRANTED){
			required.add(permission);
		}		
	}
	if(require.size() != 0){
		ActivityCompat.requestPermissions(this,required.toArray(new String[required.size()]),REQUEST_CODE_ASK_PERMISSION);
		return false;
	} else{
		return true;
	}
}

@Override
public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults){
	super.onRequestPermissionResult(requestCode,permissions,grantResults);
	if(requestCode == REQUEST_CODE_ASK_PERMISSION){
	...
	}
}

如果用户关闭了权限申请,可以在checkPermission时默认跳转至应用权限管理页面

``

Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTIONGS);
Uri uri = Uri.fromParts("package",getActivity.getPackageName(),null);
intent.setData(uri);
startActivity(intent);

Android Handler使用避免内存泄漏

``

private static class DemoHandler handler extends Handler{
	private final WeakReference mReference;
	public DemoHandler(Activity activity){
		mReference = new WeakReference<>(activity);
	}
	...
}

``

Android 中获取元素

  1. 在Activity应用元素
    ``



java代码获取:

ActivityInfo info = this.getPackageManager().getActivityInfo(getComponentName(),PackageManager.GET_META_DATA);
String msg info.metaData.getString("data_Name");

``
同理,在application应用使用ApplicationInfo获取;在service中应用,使用ComponentName获取ServiceInfo,而在Receiver中使用,则通过ComponentName获取ActivityInfo。

FragmentPagerAdapter与FragmentStatePagerAdapter

FragmentStatePagerAdapter相对于FragmentPagerAdapter多了两个全局变量:

  1. mSavedState 保存每个Fragment 的状态信息的列表。
  2. mFragments 保存每个Fragment实例对象的列表。
    不同点在:
  3. FragmentStatePagerAdapter对Fragment实例和Fragment状态进行引用保留。
  4. StateAdapter在instantiateItem方法中,创建Fragment后,读取对应Fragment状态对其进行初始化设置,并且只使用到add方法。
  5. FragmentStatePagerAdapter在destroyItem方法中,销毁Fragment时,保存其Fragment状态,并且使用remove方法移除Fragment。
  6. FragmentStatePagerAdapter重载了saveState方法和restoreState方法,在其中对于Fragment实例列表和Fragment状态列表进行保存和读取。
  • Fragment在FragmentStatePagerAdapter类的destroyItem方法中被remove时,Fragment的onDestroy方法和onDetach方法被调用到。
  • 当Fragment重新被add时,Fragment的生命周期全部重新调用,但是saveInstanceState参数保留之前存储的数据。

Android 6.0以上用户拒绝使用某些权限后,在某些功能使用时需要动态处理,调用RequestPermissions。

注:权限问题在Android gradle中配置targetSdkVersion 为6.0以下时,权限只需要在AndroidManifest中声明权限就可以,6.0以上,权限需要在AndroidManifest中配置,同时需要动态申请,否则会出现崩溃的情况。

Android 反编译无需正式签名

Android 9-Patch创建

  • 顶部:在水平拉伸的时候,保持其他位置不动,只在顶部黑色点的区域做无限的延伸
  • 左边在竖直拉伸的时候,保持其他位置不动,只在顶部黑色点的区域做无限的延伸
  • 底部在水平拉伸的时候,指定图片里的内容显示的区域
  • 右边在竖直拉伸的时候,指定图片里的内容显示的区域

问题

在Android Studio中AS对.9图增加了安全检查机制,.9图片有不规范的地方都会报编译错误——解决方式:

  1. 让AS取消对.9的图片检查
    在buildToolsVersion属性下添加
    //取消掉系统对.9图片的检查
    aapptOptions.cruncherEnabled = false
    aaptOptions.cruncherEnabled = false
  2. 检查是否重复绘制黑边,或者有哪条边没有绘制。AS要求4条边都绘制。

LayoutInflater.inflate()中的第三个参数

被填充的层是否应该附在root参数内部?如果是false,root参数只适用于为XML根元素View创建正确的LayoutParams的子类。
其实意思就是:如果attachToRoot是true的话,那第一个参数的layout文件就会被填充并附加在第二个参数所指定的ViewGroup内,方法返回结合后的View,方法返回给结合后的View,根元素是第二个参数ViewGroup。如果是false,第一个参数所指定的layout文件会被填充,并作为View返回。这个View的根元素是layout文件的根元素。不管是true或false,都需要ViewGroup的LayoutParams来正确的测量与放置layout文件所产生的View对象。

避开崩溃、异常表现与误解

  • 如果可以传入ViewGroup作为根元素,就传
  • 避免将null作为根ViewGroup
  • 当我们不负责将layout文件的View添加进ViewGroup时设置attachToRoot参数为false
  • 不要在View已经被添加进ViewGroup时传入true
  • 自定义View时很适合将attachToRoot设置为true

Android O自适应图标

在Android O在应用中创建一个备选Drawable资源res/mipmap-anydpi/ic_launcher.xml。使用元素为图标定义前景和背景图层。和都支持android:drawable属性。
在Android版本中,桌面图标大小定义为48 * 48dp。Android O必须按照以下的规范定义图层大小:

  • 两张图层大小都必须为108*108dp
  • 图层中心72*72dp范围为可视范围
  • 系统会保留四周外的36dp范围生成又去的视觉效果(如视差效果和跳动)

Android 状态栏那点事

  1. 在Android4.4+ 适配的同时,在values的style.xml中加入同名自定义style,不然4.4以下会报错
  2. 不要忘记在布局添加android:fitsSysWindows=“true”,不然布局内容会和状态栏内容重叠。
  3. 在Android 5.0中,透明的效果和4.4中有所不同但是实现方法相同,同时5.0+版本提供了新的API android:statusVarColor,可以用来单独设置状态栏颜色,但他不适用于图片占据状态栏,它是适用于纯色的状态栏,并且应该把它放到value-21文件夹中。

实际场景中通常有以下几种要求:

  • 全屏,不保留状态栏文字(Splash页面,欢迎页)

    首先在style.xml中设置为noActionBar主题

``


实现方式有三种:

``

//方式一
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
//方式二
getWindow.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN)
//方式三 style.xml中配置
//
//
  • 场景二:全屏保留状态栏文字
    ``

    Window window = getWindow();
    //默认API最低19
    if(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2){
    window.addFlags(WindowManager.LayoutParams.FLAG.TRANSLUCENT_STATUS);
    ViewGroup contentView = window.getDecorView().findViewById(Window.ID_ANDROID_CONTENT);
    contentView.getChildAt(0).setFitsSystemWindows(false);
    }

  • 场景三:标题栏和状态栏颜色一致xml中配置

``


这种处理,可以解决一些业务场景,但是如果在低于21版本手机上就不管用了,那么只有在代码中去实现:

``

Window window = getWindow();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
	window.addFlags(windowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BRACKGROUNDS);
	window.setStatusBarColor(getResources().getColor(R.color.status_toolBar_same_color));

}else {
	window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
	ViewGroup systemContent = findViewById(android.R.id.content);

	View statusBarView = new View(this);
	ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,getStatusBarHeight());
	statusBarView.setBackgroundColor(getResouces().getColor(R.color.status_toolBar_same_color));
systemContent.getChildAt(0).setFitSystemWindows(true);
systemContent.addView(statusBarView,0,lp);
}
  • 需求四:不通过Fragment对StatusBar的处理不一样

``

private void addStatusBar() {
	//条件状态栏透明,要不然不会起作用
	getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
	if(mStatusBarView == null){
		View mstatusBarView = new View(getContext());
		int screenWidth = getResources.getDisplayMetrics().widthPixels;
		int statusBarHeight = getStatusBarHeight();
		ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(screenWidth,statusBarHeight);
	  					mStatusBarView.setLayoutParams(params);
mStatusBarView.requestLayout();
		
		//获取根布局
		ViewGroup systemContent = findViewById(android.R.id.content);
		ViewGroup userContent = (ViewGroup)systmContent.getChildAt(0);
		userContent.setFitSystemWindows(false);
userContent.addView(mStatusBarView,0);
	}
}
  • 需求五:设置状态栏文字的颜色

``

//设置白底黑字
if(Build.VERSION.SDK_INIT >= Build.VERSION_CODES.M) {
	getWindow().getDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}

目前只有android 6.0以上支持修改状态栏字体。以及小米,魅族开放了修改状态栏字体的方式。

  • 需求六:切换fragment时候,toolbar和statusBar是否显示,statsBar颜色,status文字颜色

可以通过
mActivity.mStatusBarView.setVisibility(View.GONE);

小米手机应用商店下载应用更新包后不是安装,而是打开

com.android.browser.BrowserActivity启动系统自带浏览器下载

三方接入

支付宝客服态度最好,微信等都没有客服。

webView加载本地html问题

在MI5Plus 7.0系统上会加载显示不全
``

private ResponseDetail getlocal(Context context) {
    Serializer serializer = new Persister();
    InputStream inputStream = context.getResources().openRawResource(R.raw.response_detail);
    try {
        ResponseDetail bean = serializer.read(ResponseDetail.class, inputStream);
        return bean;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

.so文件位置放错导致引入资料不成功

.so文件在Android studio 中默认要放置在jniLibs文件夹下,有时候也会放在libs目录下,但是需要在gradle中添加:

  android{
	 sourceSets{
    	main {
            jniLibs.srcDirs = ['libs']
        }
    }
  }  
即重新指定jniLibs目录对应的文件夹

你可能感兴趣的:(常见问题)