Android 开发常见问题

1、Android10及以上 无法创建文件夹

解决方法:
  1. 修改gradie 中sdk版本号 29以下

  2. 使用Android规定的文件夹

  3. 添加android:requestLegacyExternalStorage=”true”到清单中。存储模型发生改变,这样是选择旧式存储模型,并且现有的外部存储代码将起作用。然后动态添加ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION 权限

2、多权限动态申请

public void checkPermission() {
	ActivityCompat.requestPermissions(MainActivity.this,
	    new String[]{
	        Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA,
            Manifest.permission.SET_ALARM,
            Manifest.permission.CHANGE_NETWORK_STATE,
            Manifest.permission.CHANGE_WIFI_STATE,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.ACCESS_WIFI_STATE,
            Manifest.permission.READ_PHONE_STATE},
         111);
}

//回调
@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 111) {
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    Tools.showToast(MainActivity.this, "缺少权限(" + permissions[i] + ")");
                    return;
                }
            }
        }
    }

3、AndroidStudio 4.0以上Swicth提示

Resource IDs will be non-final in Android Gradle Plugin version 5.0, avoid using them in switch case statements

//4.0 以上提示 id可能会改变,所有不建议使用switch catch
Switch(view.getId()){
	case R.id.btb:
		//......
		break;
	case R.id.change:
		//......
		break;
	...
	...
}

//可以改用if else ,性能几乎没有影响
int id = view.getId();
if(id == R.id.btb){
	//...........
}else if(id == R.id.change){
	//...........
}...{
}...

4、Activity、Fragment之间的交互

1)Activity访问Fragment

如果Fragment是通过布局文件添加到activity中

//fragment是通过布局文件引入的
<fragment>
	android:tag="fragment_bottom_tag"
	android:id="@+id/fragment_bottom"
	android:name="com.demo.BottomFragment"
	android:layout_width="match_parent"
	android:layout_height="50dp"
	android:layout_alignParentBottom="true"/>
</fragment>

//则有两种方式可以获取到fragment
BottomFragment fragment = (BottomFragment)getFragmentManager().findFragmentById(R.id.fragment_bottom): //通过id
BottomFragment fragment = (BottomFragment)getFragmentManager().findFragmentById("fragment_bottom_tag");//通过tag

//获取fragment中的某个控件
if(fragment != null){
	fragment.getView().findViewById(R.id.text);
}

如果fragment 是通过new Fragment() 方式获取的,则直接通过变量名操作

<frameLayout
	id="@+id/fragment_container"
	android:layout_width="match_parent"
	android:layout_height="50dp" />
	
//将Fragment添加到layout中
BottomFragment fragment = new BottomFragment();
getFragmentManager().beginTransaction()
	.add(R.id.fragment_container,fragment).commit();

fragment.getView().findViewById(R.id.text);
	
2)Fragment访问Activity

方法一、通过getActivity()方法获取,但是这种方式不好

@Override
public void onActivityCreated(....){
	//方法一(这种方式不好)在fragment中获取activity控件
	CheckBox chkMarried = (CheckBox)getActivity().findViewById(R.id.chk_married);
	button.setOnClickListener(new OnClickListener(){
		@Override
			public void onClick(View view){
					if(chkMarried.isChecked){}
			}
	});
	//如果需要获取activity中的成员变量,只需要调用activity中的get()方法
}

方式二、通过创建回调函数来实现
Fragment与其附属着的activity之间的通信的最佳方式:
1、在发起事件的Fragment中定义一个接口,接口中声明你的方法
2、在onAttach方法中要求activity实现这个接口
3、在Activity中实现该方法

1、在fragmeng中定义接口
public interface OnNewItemAddListener{
	public void newItemAdded(String content);
}
2、声明接口引用变量
private OnNewItemAddListener onNewItemAddListener;
3、在fragment的onAttach方法中要求activity实现这个方法
@Override
public void Attach(Activity activity){
	super.onAttach(activity);
	//要求该ftragment所附着的Activity必须完成这个方法的实现
	try{
		onNewItemAddListener = (OnNewItemAddListener) activity;
	}catch(ClassCastException e){
	}
}
4、在fragment中 需要的事件内 调用接口方法
onNewItemAddListenter.newItemAdded("");

5、在activity中必须实现接口
public class IndexActivity extends Activity implements OnNewItemAddListener{
	。。。
	。。。
	@Override
	public void newItemAdd(String content){
		//操作fragment传过来的content
	}
}

3)所有Fragment之间的通信

所有Fragment之间的通信,都应该通过他们所属的Activity来完成,不能是多个Fragment之间的直接通信、调用(尽管可以)

5、JAVA-startActivityResult 替代

用registerForActivityResult替代即可

ActivityResultLauncher launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                //此处是跳转的result回调方法
                if (result.getData() != null && result.getResultCode() == Activity.RESULT_OK) {
                    Tools.showToast(context,"返回成功");
                } else {
                    Tools.showToast(context,"返回失败");
                }
            }
        });

注意:registerForActivityResult的初始化需要在onCreate中进行

调用

Intent intent = new Intent(context, Second.class);
 launcher.launch(intent);

6、DataBinding 提示找不到类

在布局文间中引入类后:

<data>
        <variable
            name="idol"
            type="com.kaiya.mvp.jetpacktest.DataBindingF.Idol" />
    </data>

提示找不到 “com.kaiya.mvp.jetpacktest.dataBindingF.Idol”
原因:
Gradle4.6版本升级之前,包文件名首字母大小写都可以,升级以后文件名必须小写字母开头。所以需要将包文件名首字母改为小写
如下代码,将 “DataBindingF” 改为 “dataBindingF”

<data>
        <variable
            name="idol"
            type="com.kaiya.mvp.jetpacktest.dataBindingF.Idol" />
    </data>

7、DataBinding 提示 Cause: couldn’t make a guss for

在引入事件类时

<variable
	name="eventHandle"
	type="com.kaiya.mvp.jetpacktest.dataBindingF.eventHandleListener" />

提示 “使用dataBinding报错:Cause: couldn‘t make a guess for的解决办法”
原因:
是类名没遵循大驼峰命名法(首字母大写)导致的(eventHandleListener 首字母没有大写)

改成首字母大写就好了:

<variable
	name="eventHandle"
	//eventHandlerListener 首字母改为大写了 -> EventHandlerListener
	type="com.kaiya.mvp.jetpacktest.dataBindingF.EventHandleListener" /> 

8、ViewBinding 与 DataBinding区别

https://developer.aliyun.com/article/938714

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值