Open Discovery-Prachi opened 4 years ago
Thanks for the bug report.
That's weird, looks like the log statement is failing: https://github.com/facebook/fresco/blob/e791687a6617eaeb5f8e5524452541777ddc4aa4/imagepipeline-base/src/main/java/com/facebook/imagepipeline/transcoder/DownsampleUtil.java#L103
Setting your log level to anything that's smaller than verbose (like ERROR or WARN) should help: FLog.setMinimumLoggingLevel(WARN)
Ideally, we should figure out why String.format is failing here.
I was curious about the problem the other day, even without the evidence and ability to reproduce it. Here is what I've found.
Initially, I was thinking that the problem somehow related to the locale that has not been set up in FLog.formatString()
However, there are three concerns.
First of all, in the particular example FLog.v()
works with the conversion from primitives to String
, not vice-versa. So, probably, there is no need to worry about Locale
problems like ,
(comma) or .
(dot) for decimals.
Second, despite the fact of the @NonNull
argument, String.format()
allows passing null Locale
Nevertheless, String.format
has overloading without passing Locale
that sets just to default Locale
for Formatter
.
I believe, the reason behind setting it to the null
in the FLog.formatString()
is that Lint has a LocaleDetector check that reminds about that decision. So, probably, that was a way to suppress it? If it is then, I believe, it's not a good practice.
And the last concern is the reason why NPE
happens in the first place.
If to look down the road of the stack, the problem is in Formatter.addZeroes()
where it's simply one of the arguments, char[] v
which is not guarded
Back to the caller, print()
shows that this is a mantissa which converts from double
value to char[]
with help of FormattedFloatingDecimal
FormattedFloatingDecimal
is part of the sun.misc
package that is not Android-Changed.
And it's possible to obtain a null
mantissa since it's not guarded.
However, in all cases of the constructor logic mantissa has to be assigned, even if it's just new char[0]
.
At the same time, I've found that WebRTC
team that is part of the Android SDK has faced the same problem 2 years ago where they specified it as
crashes... on some devices
and suggests a Speculative fix by using DecimalFormat
instead of String.Format
for floats.
By the way, initially, they've had used Locale.US
in String.Format
while getting the problem, so it's feasible to assume the problem is not related to the Locale
.
On the other hand, DecimalFormat
doesn't use anything from sun.misc
packages.
Conclusion.
I'm curious if the problem anyhow correlated with the fact that it's about FormattedFloatingDecimal
from sun.misc
package. Maybe these devices have been using some sort of customized AOSP? I've found no other evidence of the problem than that with WebRTC
.
Speculative fix is to use DecimalFormat
. The problem is that it has to be done through FLog.formatString()
since the problem is in there.
@pnkshir it would be great to have a bit more information about the devices with crashes if it's possible. @oprisnik Please, let me know what you think and if there are enough reasons to apply a Speculative fix.
Hi, Our users are having the same problem on Android 8.1.0, but not on Fresco. These are the devices: Xiaomi Redmi 6 Pro Xiaomi Redmi 5 Plus Vivo V1818A Vivo V1732A Samsung Galaxy J7(2016) Samsung Galaxy J2 Core OPPO A5 Huawei Y3 2018
It is failing on formatting the latitude and longitude (double
):
String.format(Locale.ENGLISH, "%.6f", latitude)
Hey @tsybanov - thank you for the detailed report and sorry for the late reply.
I think we should try your speculative fix, so it would be great if you could submit a PR.
yet another device
vivo(vivo Y85A) on android 8.1
Can you please explain the issue(#2504) a little bit to understand the issue well. I would like to contribute to this issue.
Hi All Friend I Need Your Help to Fix This java.lang.RuntimeException: at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3654) at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3812) at android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:83) at android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2267) at android.os.Handler.dispatchMessage (Handler.java:107) at android.os.Looper.loop (Looper.java:237) at android.app.ActivityThread.main (ActivityThread.java:8161) at java.lang.reflect.Method.invoke (Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:496) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1100) Caused by: java.lang.NullPointerException: at com.deepthistudio.sinhalabehethapp.Logo_Screen.onCreate (Logo_Screen.java:19) at android.app.Activity.performCreate (Activity.java:7963) at android.app.Activity.performCreate (Activity.java:7952) at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1307) at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3629)
I am a newbie and willing to contribute to this project. Can I get started with this please.
I am a newbie and willing to contribute to this project. Can I get started with this please.
Can someone help me with understanding the codebase I am a newbie just starting to contribute. Please
I am curious to hear if the speculative fix has worked?
@jacklyq The PR: https://github.com/facebook/fresco/pull/2552 was never approved
On your onStart method, you are using the Connectivity.isConnected method without checking if it returns true. If the device is not connected, it will proceed to show a Toast message but still attempt to execute the code inside the postDelayed handler, which might lead to issues.
Here's an updated version of the onStart method with proper null checks and restructured logic:
@Override
protected void onStart() {
super.onStart();
Context context = getApplicationContext();
if (Connectivity.isConnected(context)) {
final MySharedPreferences mySharedPreferences = new MySharedPreferences(this);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (mySharedPreferences != null && mySharedPreferences.getBooleanVal(key_first_install)) {
Intent intent = new Intent(Logo_screen.this, dang_nhap.class);
startActivity(intent);
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_left);
finish();
} else {
Intent intent = new Intent(Logo_screen.this, waiting.class);
if (mySharedPreferences != null) {
mySharedPreferences.putBooleanVal(key_first_install, true);
}
startActivity(intent);
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_left);
finish();
}
}
}, SPLASH_SCREEN);
} else {
Toast.makeText(context, "show a toast msg ", Toast.LENGTH_SHORT).show();
}
}
This modification includes null checks for mySharedPreferences before using it. Additionally, the Connectivity.isConnected check is used to decide whether to proceed with the delayed task or simply show a toast message if there is no network connectivity.
This is from the class Logo_Screen.java
Hey, Is anyone ready to help me out understand the issue more clearly? I've just started contributing and am curious to learn more.
We are getting following crash on Crashlytics for good number of users with Android OS 8, with more than 47 devices. We are using "com.facebook.fresco:fresco:2.2.0"
Could you please help us, since its happening on. multiple users.
Logs :
Fatal Exception: java.lang.NullPointerException: Attempt to get length of null array at java.util.Formatter$FormatSpecifier.addZeros(Formatter.java:3505) at java.util.Formatter$FormatSpecifier.print(Formatter.java:3401) at java.util.Formatter$FormatSpecifier.print(Formatter.java:3332) at java.util.Formatter$FormatSpecifier.print(Formatter.java:3317) at java.util.Formatter$FormatSpecifier.printFloat(Formatter.java:2891) at java.util.Formatter$FormatSpecifier.print(Formatter.java:2844) at java.util.Formatter.format(Formatter.java:2523) at java.util.Formatter.format(Formatter.java:2458) at java.lang.String.format(String.java:2814) at com.facebook.common.logging.FLog.formatString(FLog.java:491) at com.facebook.common.logging.FLog.v(FLog.java:118) at com.facebook.imagepipeline.transcoder.DownsampleUtil.determineDownsampleRatio(DownsampleUtil.java:87) at com.facebook.imagepipeline.transcoder.DownsampleUtil.determineSampleSize(DownsampleUtil.java:43) at com.facebook.imagepipeline.producers.DecodeProducer$ProgressiveDecoder$1.run(DecodeProducer.java:163) at com.facebook.imagepipeline.producers.JobScheduler.doJob(JobScheduler.java:202) at com.facebook.imagepipeline.producers.JobScheduler.access$000(JobScheduler.java:22) at com.facebook.imagepipeline.producers.JobScheduler$1.run(JobScheduler.java:73) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at com.facebook.imagepipeline.core.PriorityThreadFactory$1.run(PriorityThreadFactory.java:51) at java.lang.Thread.run(Thread.java:764)