Skip to content

Commit 350a1d6

Browse files
committed
增加对android q的适配,绕过mFactorySet的调用(暂不发布)
1 parent cb9811a commit 350a1d6

7 files changed

Lines changed: 203 additions & 112 deletions

File tree

androidx/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
apply plugin: 'com.android.application'
22

33
android {
4-
compileSdkVersion 28
4+
compileSdkVersion 29
55

66

77
defaultConfig {
88
minSdkVersion 16
9-
targetSdkVersion 28
9+
targetSdkVersion 29
1010
versionCode 1
1111
versionName "1.0"
1212

@@ -40,8 +40,8 @@ dependencies {
4040

4141
// If you want pre-written Activities and Fragments you can subclass as providers
4242
implementation 'com.trello.rxlifecycle3:rxlifecycle-components:3.0.0'
43-
// implementation project(':libraryx')
44-
implementation 'com.noober.background:corex:1.5.4-ALPHA'
43+
implementation project(':libraryx')
44+
// implementation 'com.noober.background:corex:1.5.4-ALPHA'
4545
}
4646

4747
repositories{

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dependencies {
3737
testImplementation 'junit:junit:4.12'
3838
androidTestImplementation 'com.android.support.test:runner:1.0.2'
3939
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
40-
implementation 'com.noober.background:core:1.5.4'
41-
// implementation project(':library')
40+
// implementation 'com.noober.background:core:1.5.4'
41+
implementation project(':library')
4242
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
4343
}

app/src/main/java/com/noober/backgroudlibrary/MainActivity.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
2525
setContentView( R.layout.activity_main);
2626
getSupportFragmentManager().beginTransaction().add(R.id.fl_content, new BlankFragment()).commitAllowingStateLoss();
2727
Button button = findViewById(R.id.btn);
28-
2928
button.setOnClickListener(new View.OnClickListener() {
3029
@Override
3130
public void onClick(View v) {

app/src/main/java/com/noober/backgroudlibrary/MyApplication.java

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,41 @@ public class MyApplication extends Application {
1414
@Override
1515
public void onCreate() {
1616
super.onCreate();
17-
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
18-
@Override
19-
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
20-
BackgroundLibrary.inject(activity);
21-
}
22-
23-
@Override
24-
public void onActivityStarted(Activity activity) {
25-
26-
}
27-
28-
@Override
29-
public void onActivityResumed(Activity activity) {
30-
31-
}
32-
33-
@Override
34-
public void onActivityPaused(Activity activity) {
35-
36-
}
37-
38-
@Override
39-
public void onActivityStopped(Activity activity) {
40-
41-
}
42-
43-
@Override
44-
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
45-
46-
}
47-
48-
@Override
49-
public void onActivityDestroyed(Activity activity) {
50-
51-
}
52-
});
17+
// registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
18+
// @Override
19+
// public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
20+
// BackgroundLibrary.inject(activity);
21+
// }
22+
//
23+
// @Override
24+
// public void onActivityStarted(Activity activity) {
25+
//
26+
// }
27+
//
28+
// @Override
29+
// public void onActivityResumed(Activity activity) {
30+
//
31+
// }
32+
//
33+
// @Override
34+
// public void onActivityPaused(Activity activity) {
35+
//
36+
// }
37+
//
38+
// @Override
39+
// public void onActivityStopped(Activity activity) {
40+
//
41+
// }
42+
//
43+
// @Override
44+
// public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
45+
//
46+
// }
47+
//
48+
// @Override
49+
// public void onActivityDestroyed(Activity activity) {
50+
//
51+
// }
52+
// });
5353
}
5454
}

app/src/main/res/layout/activity_main.xml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
android:gravity="center"
2323
android:text="指定只显示左右下方的边框"
2424
android:textSize="20sp"
25-
app:bl_stroke_width="1dp"
26-
app:bl_stroke_color="@android:color/black"
2725
app:bl_solid_color="@android:color/white"
28-
app:bl_stroke_position="left|bottom|right"/>
26+
app:bl_stroke_color="@android:color/black"
27+
app:bl_stroke_position="left|bottom|right"
28+
app:bl_stroke_width="1dp" />
2929

3030
<com.noober.background.view.BLTextView
3131
android:id="@+id/ttt"
@@ -45,9 +45,9 @@
4545

4646
<com.noober.background.view.BLView
4747
android:id="@+id/v_anim"
48-
android:layout_marginTop="10dp"
4948
android:layout_width="wrap_content"
5049
android:layout_height="wrap_content"
50+
android:layout_marginTop="10dp"
5151
app:bl_anim_auto_start="true"
5252
app:bl_duration="50"
5353
app:bl_frame_drawable_item0="@drawable/img00"
@@ -108,11 +108,11 @@
108108
android:textSize="18dp"
109109
android:textStyle="bold"
110110
app:bl_corners_radius="3dp"
111-
app:bl_shape="rectangle"
112-
app:bl_stroke_width="1dp"
113111
app:bl_multi_selector1="-state_enabled,#9DD1F6"
114112
app:bl_multi_selector2="state_pressed,#9DD1F6"
115-
app:bl_multi_selector3="-state_pressed,#1B82D1"/>
113+
app:bl_multi_selector3="-state_pressed,#1B82D1"
114+
app:bl_shape="rectangle"
115+
app:bl_stroke_width="1dp" />
116116

117117
<com.noober.background.view.BLButton
118118
android:layout_width="300dp"
@@ -126,9 +126,9 @@
126126
android:textSize="18dp"
127127
android:textStyle="bold"
128128
app:bl_corners_radius="3dp"
129+
app:bl_pressed_drawable="#9DD1F6"
129130
app:bl_shape="rectangle"
130131
app:bl_stroke_width="1dp"
131-
app:bl_pressed_drawable="#9DD1F6"
132132
app:bl_unEnabled_drawable="#9DD1F6"
133133
app:bl_unPressed_drawable="#1B82D1" />
134134

@@ -494,5 +494,10 @@
494494

495495
</FrameLayout>
496496

497+
<!--<fragment-->
498+
<!--android:id="@+id/fragmentTest"-->
499+
<!--android:name="com.noober.backgroudlibrary.BlankFragment"-->
500+
<!--android:layout_width="match_parent"-->
501+
<!--android:layout_height="match_parent" />-->
497502
</LinearLayout>
498503
</android.support.v4.widget.NestedScrollView>

library/src/main/java/com/noober/background/BackgroundLibrary.java

Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,22 @@
22

33
import android.app.Activity;
44
import android.content.Context;
5+
import android.support.annotation.NonNull;
6+
import android.support.v4.view.LayoutInflaterCompat;
57
import android.support.v7.app.AppCompatActivity;
68
import android.support.v7.app.AppCompatDelegate;
79
import android.util.AttributeSet;
810
import android.view.LayoutInflater;
911
import android.view.View;
1012

1113
import java.lang.reflect.Field;
14+
import java.lang.reflect.InvocationTargetException;
15+
import java.lang.reflect.Method;
1216

1317
/**
1418
* minSdkVersion最小为14,建议minSdkVersion >= 16
1519
* 如果minSdkVersion < 16:bl_gradient_angle, bl_gradient_startColor, bl_gradient_centerColor, bl_gradient_endColor会失效,其他正常
16-
*
20+
* <p>
1721
* Created by xiaoqi on 2018/9/9
1822
*/
1923
public class BackgroundLibrary {
@@ -25,30 +29,37 @@ public static LayoutInflater inject(Context context) {
2529
} else {
2630
inflater = LayoutInflater.from(context);
2731
}
28-
if(inflater == null){
32+
if (inflater == null) {
2933
return null;
3034
}
31-
if(inflater.getFactory2() == null){
32-
BackgroundFactory factory = new BackgroundFactory();
33-
if (context instanceof AppCompatActivity) {
34-
final AppCompatDelegate delegate = ((AppCompatActivity) context).getDelegate();
35-
factory.setInterceptFactory(new LayoutInflater.Factory() {
36-
@Override
37-
public View onCreateView(String name, Context context, AttributeSet attrs) {
38-
return delegate.createView(null, name, context, attrs);
39-
}
40-
});
41-
}
35+
if (inflater.getFactory2() == null) {
36+
BackgroundFactory factory = setDelegateFactory(context);
4237
inflater.setFactory2(factory);
43-
}else if(!(inflater.getFactory2() instanceof BackgroundFactory)){
44-
forceSetFactory2(inflater);
38+
} else if (!(inflater.getFactory2() instanceof BackgroundFactory)) {
39+
forceSetFactory2(inflater, context);
4540
}
4641
return inflater;
4742
}
4843

44+
@NonNull
45+
private static BackgroundFactory setDelegateFactory(Context context) {
46+
BackgroundFactory factory = new BackgroundFactory();
47+
if (context instanceof AppCompatActivity) {
48+
final AppCompatDelegate delegate = ((AppCompatActivity) context).getDelegate();
49+
factory.setInterceptFactory(new LayoutInflater.Factory() {
50+
@Override
51+
public View onCreateView(String name, Context context, AttributeSet attrs) {
52+
return delegate.createView(null, name, context, attrs);
53+
}
54+
});
55+
}
56+
return factory;
57+
}
58+
4959
/**
5060
* used for activity which has addFactory
5161
* 如果因为其他库已经设置了factory,可以使用该方法去进行inject,在其他库的setFactory后面调用即可
62+
*
5263
* @param context
5364
*/
5465
public static LayoutInflater inject2(Context context) {
@@ -58,32 +69,64 @@ public static LayoutInflater inject2(Context context) {
5869
} else {
5970
inflater = LayoutInflater.from(context);
6071
}
61-
if(inflater == null){
72+
if (inflater == null) {
6273
return null;
6374
}
64-
forceSetFactory2(inflater);
75+
forceSetFactory2(inflater, context);
6576
return inflater;
6677
}
6778

68-
private static void forceSetFactory2(LayoutInflater inflater) {
79+
/**
80+
* 通过LayoutInflaterCompat去规避非SDK接口在Android Q 中的受限。
81+
* 首先:设置LayoutInflaterCompat的sCheckedField为false, 保证可以设置当前mFactory2的值
82+
* 第二:设置LayoutInflater的 mFactory 为空,保证LayoutInflaterCompat调用setFactory的时候不进行FactoryMerger操作
83+
* 第三:反射调用LayoutInflaterCompat的forceSetFactory2方法
84+
* 第四:重新设置LayoutInflater的mFactory值,防止调用Fragment的时候fragment会进行FactoryMerger操作
85+
* 经过上述步骤,在Activity以及Activity中的Fragment就会变成我们想要的factory类
86+
*/
87+
private static void forceSetFactory2(LayoutInflater inflater, Context context) {
88+
Class<LayoutInflaterCompat> compatClass = LayoutInflaterCompat.class;
89+
Class<LayoutInflater> inflaterClass = LayoutInflater.class;
6990
try {
70-
Field field = LayoutInflater.class.getDeclaredField("mFactorySet");
71-
field.setAccessible(true);
72-
field.setBoolean(inflater, false);
91+
Field sCheckedField = compatClass.getDeclaredField("sCheckedField");
92+
sCheckedField.setAccessible(true);
93+
sCheckedField.setBoolean(inflater, false);
94+
Field mFactory = inflaterClass.getDeclaredField("mFactory");
95+
mFactory.setAccessible(true);
96+
mFactory.set(inflater, null);
7397

74-
BackgroundFactory factory = new BackgroundFactory();
75-
if (inflater.getFactory2() != null) {
76-
factory.setInterceptFactory2(inflater.getFactory2());
77-
} else if (inflater.getFactory() != null) {
78-
factory.setInterceptFactory(inflater.getFactory());
79-
}
80-
inflater.setFactory2(factory);
81-
} catch (NoSuchFieldException e) {
82-
e.printStackTrace();
83-
} catch (IllegalArgumentException e) {
98+
Method method = compatClass.getDeclaredMethod("forceSetFactory2", LayoutInflater.class, LayoutInflater.Factory2.class);
99+
method.setAccessible(true);
100+
BackgroundFactory factory = setDelegateFactory(context);
101+
method.invoke(null, inflater, factory);
102+
mFactory.set(inflater, factory);
103+
} catch (NoSuchMethodException e) {
84104
e.printStackTrace();
85105
} catch (IllegalAccessException e) {
86106
e.printStackTrace();
107+
} catch (InvocationTargetException e) {
108+
e.printStackTrace();
109+
} catch (NoSuchFieldException e) {
110+
e.printStackTrace();
87111
}
112+
// try {
113+
// Field field = LayoutInflater.class.getDeclaredField("mFactorySet");
114+
// field.setAccessible(true);
115+
// field.setBoolean(inflater, false);
116+
//
117+
// BackgroundFactory factory = new BackgroundFactory();
118+
// if (inflater.getFactory2() != null) {
119+
// factory.setInterceptFactory2(inflater.getFactory2());
120+
// } else if (inflater.getFactory() != null) {
121+
// factory.setInterceptFactory(inflater.getFactory());
122+
// }
123+
// inflater.setFactory2(factory);
124+
// } catch (NoSuchFieldException e) {
125+
// e.printStackTrace();
126+
// } catch (IllegalArgumentException e) {
127+
// e.printStackTrace();
128+
// } catch (IllegalAccessException e) {
129+
// e.printStackTrace();
130+
// }
88131
}
89132
}

0 commit comments

Comments
 (0)