weex-bot commented on issue #2731: Add Lint in TravisCI and Update iOS TravisCI URL: https://github.com/apache/incubator-weex/pull/2731#issuecomment-516690354 <!-- 0 failure: 2 warning: <?xml version="1...., ## AndroidLint Re... DangerID: danger-id-androidlint; --> <table> <thead> <tr> <th width="50"></th> <th width="100%" data-danger-table="true">Warnings</th> </tr> </thead> <tbody><tr> <td>:warning:</td> <td> <?xml version="1.0" encoding="UTF-8"?> <issues format="5" by="lint 3.3.2"> <issue id="MissingPermission" severity="Error" message="Missing permissions required by TelephonyManager.getDeviceId: android.permission.READ_PHONE_STATE" category="Correctness" priority="9" summary="Missing Permissions" explanation="This check scans through your code and libraries and looks at the APIs being used, and checks this against the set of permissions required to access those APIs. If the code using those APIs is called at runtime, then the program will crash.

Furthermore, for permissions that are revocable (with targetSdkVersion 23), client code must also be prepared to handle the calls throwing an exception if the user rejects the request for permission at runtime." errorLine1=" return sApplication == null ? "" : ((TelephonyManager) sApplication" errorLine2=" ^"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java" line="400" column="40"/> </issue> <issue id="CanvasSize" severity="Warning" message="Calling `Canvas.getHeight()` is usually wrong; you should be calling `getBounds().getHeight()` instead" category="Correctness" priority="6" summary="Wrong Canvas Size" explanation="In a custom view's draw implementation, you should normally call `getWidth` and `getHeight` on the custom view itself, not on the `canvas` instance.

Canvas width and height are the width and height of the `Canvas`, which is not always the same as size of the view.

In the hardware accelerated path the width and height of the canvas typically always match that of the `View` because every view goes to its own recorded `DisplayList`. But in software rendering there's just one canvas that is clipped and transformed as it makes its way through the `View` tree, and otherwise remains the same `Canvas` object for every View's draw method.

You should only use Canvas state to adjust how much you draw, such as a quick-reject for early work avoidance if it's going to be clipped away, but not what you draw." errorLine1=" Path border = mBackgroundDrawable.getContentPath(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()));" errorLine2=" ~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java" line="1685" column="101"/> </issue> <issue id="CanvasSize" severity="Warning" message="Calling `Canvas.getWidth()` is usually wrong; you should be calling `getBounds().getWidth()` instead" category="Correctness" priority="6" summary="Wrong Canvas Size" explanation="In a custom view's draw implementation, you should normally call `getWidth` and `getHeight` on the custom view itself, not on the `canvas` instance.

Canvas width and height are the width and height of the `Canvas`, which is not always the same as size of the view.

In the hardware accelerated path the width and height of the canvas typically always match that of the `View` because every view goes to its own recorded `DisplayList`. But in software rendering there's just one canvas that is clipped and transformed as it makes its way through the `View` tree, and otherwise remains the same `Canvas` object for every View's draw method.

You should only use Canvas state to adjust how much you draw, such as a quick-reject for early work avoidance if it's going to be clipped away, but not what you draw." errorLine1=" Path border = mBackgroundDrawable.getContentPath(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()));" errorLine2=" ~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java" line="1685" column="82"/> </issue> <issue id="DefaultLocale" severity="Warning" message="Implicitly using the default locale is a common source of bugs: Use `String.format(Locale, ...)` instead" category="Correctness" priority="6" summary="Implied default locale in case conversion" explanation="Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying an explicit locale** is a common source of bugs. The reason for that is that those methods will use the current locale on the user's device, and even though the code appears to work correctly when you are developing the app, it will fail in some locales. For example, in the Turkish locale, the uppercase replacement for `i` is **not** `I`.

If you want the methods to just perform ASCII replacement, for example to convert an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to use the current locale, call `String#toUpperCase(Locale.getDefault())` instead." url="http://developer.android.com/reference/java/util/Locale.html#default_locale" urls="http://developer.android.com/reference/java/util/Locale.html#default_locale" errorLine1=" String.format("cell:[w:%d,h:%d],attrs:%s,styles:%s",realWidth,realHeight,getAttrs(),getStyles())" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java" line="983" column="13"/> </issue> <issue id="DefaultLocale" severity="Warning" message="Implicitly using the default locale is a common source of bugs: Use `toUpperCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`." category="Correctness" priority="6" summary="Implied default locale in case conversion" explanation="Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying an explicit locale** is a common source of bugs. The reason for that is that those methods will use the current locale on the user's device, and even though the code appears to work correctly when you are developing the app, it will fail in some locales. For example, in the Turkish locale, the uppercase replacement for `i` is **not** `I`.

If you want the methods to just perform ASCII replacement, for example to convert an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to use the current locale, call `String#toUpperCase(Locale.getDefault())` instead." url="http://developer.android.com/reference/java/util/Locale.html#default_locale" urls="http://developer.android.com/reference/java/util/Locale.html#default_locale" errorLine1=" if(SYS_VERSION != null && SYS_VERSION.toUpperCase().equals("P")){" errorLine2=" ~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java" line="61" column="43"/> </issue> <issue id="DefaultLocale" severity="Warning" message="Implicitly using the default locale is a common source of bugs: Use `toUpperCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`." category="Correctness" priority="6" summary="Implied default locale in case conversion" explanation="Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying an explicit locale** is a common source of bugs. The reason for that is that those methods will use the current locale on the user's device, and even though the code appears to work correctly when you are developing the app, it will fail in some locales. For example, in the Turkish locale, the uppercase replacement for `i` is **not** `I`.

If you want the methods to just perform ASCII replacement, for example to convert an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to use the current locale, call `String#toUpperCase(Locale.getDefault())` instead." url="http://developer.android.com/reference/java/util/Locale.html#default_locale" urls="http://developer.android.com/reference/java/util/Locale.html#default_locale" errorLine1=" if(SYS_VERSION != null && SYS_VERSION.toUpperCase().equals("Q")){" errorLine2=" ~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java" line="64" column="43"/> </issue> <issue id="DefaultLocale" severity="Warning" message="Implicitly using the default locale is a common source of bugs: Use `String.format(Locale, ...)` instead" category="Correctness" priority="6" summary="Implied default locale in case conversion" explanation="Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying an explicit locale** is a common source of bugs. The reason for that is that those methods will use the current locale on the user's device, and even though the code appears to work correctly when you are developing the app, it will fail in some locales. For example, in the Turkish locale, the uppercase replacement for `i` is **not** `I`.

If you want the methods to just perform ASCII replacement, for example to convert an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to use the current locale, call `String#toUpperCase(Locale.getDefault())` instead." url="http://developer.android.com/reference/java/util/Locale.html#default_locale" urls="http://developer.android.com/reference/java/util/Locale.html#default_locale" errorLine1=" String.format("imgSize:[%d,%d],viewSize:[%d,%d],urL:%s",imgWidth,imgHeight,imageView.getMeasuredWidth(),imageView.getMeasuredHeight()" errorLine2=" ^"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXImage.java" line="487" column="15"/> </issue> <issue id="DefaultLocale" severity="Warning" message="Implicitly using the default locale is a common source of bugs: Use `toLowerCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`." category="Correctness" priority="6" summary="Implied default locale in case conversion" explanation="Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying an explicit locale** is a common source of bugs. The reason for that is that those methods will use the current locale on the user's device, and even though the code appears to work correctly when you are developing the app, it will fail in some locales. For example, in the Turkish locale, the uppercase replacement for `i` is **not** `I`.

If you want the methods to just perform ASCII replacement, for example to convert an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to use the current locale, call `String#toUpperCase(Locale.getDefault())` instead." url="http://developer.android.com/reference/java/util/Locale.html#default_locale" urls="http://developer.android.com/reference/java/util/Locale.html#default_locale" errorLine1=" direction = direction.replaceAll("\\s*", "").toLowerCase();" errorLine2=" ~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/utils/WXResourceUtils.java" line="337" column="52"/> </issue> <issue id="DefaultLocale" severity="Warning" message="Implicitly using the default locale is a common source of bugs: Use `toLowerCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`." category="Correctness" priority="6" summary="Implied default locale in case conversion" explanation="Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying an explicit locale** is a common source of bugs. The reason for that is that those methods will use the current locale on the user's device, and even though the code appears to work correctly when you are developing the app, it will fail in some locales. For example, in the Turkish locale, the uppercase replacement for `i` is **not** `I`.

If you want the methods to just perform ASCII replacement, for example to convert an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to use the current locale, call `String#toUpperCase(Locale.getDefault())` instead." url="http://developer.android.com/reference/java/util/Locale.html#default_locale" urls="http://developer.android.com/reference/java/util/Locale.html#default_locale" errorLine1=" mAbi = mAbi.toLowerCase();" errorLine2=" ~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java" line="361" column="19"/> </issue> <issue id="DefaultLocale" severity="Warning" message="Implicitly using the default locale is a common source of bugs: Use `toUpperCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`." category="Correctness" priority="6" summary="Implied default locale in case conversion" explanation="Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying an explicit locale** is a common source of bugs. The reason for that is that those methods will use the current locale on the user's device, and even though the code appears to work correctly when you are developing the app, it will fail in some locales. For example, in the Turkish locale, the uppercase replacement for `i` is **not** `I`.

If you want the methods to just perform ASCII replacement, for example to convert an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to use the current locale, call `String#toUpperCase(Locale.getDefault())` instead." url="http://developer.android.com/reference/java/util/Locale.html#default_locale" urls="http://developer.android.com/reference/java/util/Locale.html#default_locale" errorLine1=" if (method != null) method = method.toUpperCase();" errorLine2=" ~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/http/WXStreamModule.java" line="79" column="41"/> </issue> <issue id="DefaultLocale" severity="Warning" message="Implicitly using the default locale is a common source of bugs: Use `toUpperCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`." category="Correctness" priority="6" summary="Implied default locale in case conversion" explanation="Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying an explicit locale** is a common source of bugs. The reason for that is that those methods will use the current locale on the user's device, and even though the code appears to work correctly when you are developing the app, it will fail in some locales. For example, in the Turkish locale, the uppercase replacement for `i` is **not** `I`.

If you want the methods to just perform ASCII replacement, for example to convert an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to use the current locale, call `String#toUpperCase(Locale.getDefault())` instead." url="http://developer.android.com/reference/java/util/Locale.html#default_locale" urls="http://developer.android.com/reference/java/util/Locale.html#default_locale" errorLine1=" if (method != null) method = method.toUpperCase();" errorLine2=" ~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/http/WXStreamModule.java" line="160" column="41"/> </issue> <issue id="DefaultLocale" severity="Warning" message="Implicitly using the default locale is a common source of bugs: Use `toLowerCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`." category="Correctness" priority="6" summary="Implied default locale in case conversion" explanation="Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying an explicit locale** is a common source of bugs. The reason for that is that those methods will use the current locale on the user's device, and even though the code appears to work correctly when you are developing the app, it will fail in some locales. For example, in the Turkish locale, the uppercase replacement for `i` is **not** `I`.

If you want the methods to just perform ASCII replacement, for example to convert an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to use the current locale, call `String#toUpperCase(Locale.getDefault())` instead." url="http://developer.android.com/reference/java/util/Locale.html#default_locale" urls="http://developer.android.com/reference/java/util/Locale.html#default_locale" errorLine1=" return headers.get(key.toLowerCase());" errorLine2=" ~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/http/WXStreamModule.java" line="237" column="30"/> </issue> <issue id="DefaultLocale" severity="Warning" message="Implicitly using the default locale is a common source of bugs: Use `toLowerCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`." category="Correctness" priority="6" summary="Implied default locale in case conversion" explanation="Calling `String#toLowerCase()` or `#toUpperCase()` **without specifying an explicit locale** is a common source of bugs. The reason for that is that those methods will use the current locale on the user's device, and even though the code appears to work correctly when you are developing the app, it will fail in some locales. For example, in the Turkish locale, the uppercase replacement for `i` is **not** `I`.

If you want the methods to just perform ASCII replacement, for example to convert an enum name, call `String#toUpperCase(Locale.US)` instead. If you really want to use the current locale, call `String#toUpperCase(Locale.getDefault())` instead." url="http://developer.android.com/reference/java/util/Locale.html#default_locale" urls="http://developer.android.com/reference/java/util/Locale.html#default_locale" errorLine1=" Matcher matcher = CHARSET_PATTERN.matcher(cType.toLowerCase());" errorLine2=" ~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/http/WXStreamModule.java" line="246" column="55"/> </issue> <issue id="InlinedApi" severity="Warning" message="Field requires API level 17 (current min is 14): `android.view.View#LAYOUT_DIRECTION_LTR`" category="Correctness" priority="6" summary="Using inlined constants on older versions" explanation="This check scans through all the Android API field references in the application and flags certain constants, such as static final integers and Strings, which were introduced in later versions. These will actually be copied into the class files rather than being referenced, which means that the value is available even when running on older devices. In some cases that's fine, and in other cases it can result in a runtime crash or incorrect behavior. It depends on the context, so consider the code carefully and decide whether it's safe and can be suppressed or whether the code needs to be guarded.

If you really want to use this API and don't need to support older devices just set the `minSdkVersion` in your `build.gradle` or `AndroidManifest.xml` files.
If your code is **deliberately** accessing newer APIs, and you have ensured (e.g. with conditional execution) that this code will only ever be called on a supported platform, then you can annotate your class or method with the `@TargetApi` annotation specifying the local minimum SDK to apply, such as `@TargetApi(11)`, such that this check considers 11 rather than your manifest file's minimum SDK as the required API level." errorLine1=" int layoutDirection = component.isLayoutRTL() ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java" line="202" column="83"/> </issue> <issue id="InlinedApi" severity="Warning" message="Field requires API level 17 (current min is 14): `android.view.View#LAYOUT_DIRECTION_RTL`" category="Correctness" priority="6" summary="Using inlined constants on older versions" explanation="This check scans through all the Android API field references in the application and flags certain constants, such as static final integers and Strings, which were introduced in later versions. These will actually be copied into the class files rather than being referenced, which means that the value is available even when running on older devices. In some cases that's fine, and in other cases it can result in a runtime crash or incorrect behavior. It depends on the context, so consider the code carefully and decide whether it's safe and can be suppressed or whether the code needs to be guarded.

If you really want to use this API and don't need to support older devices just set the `minSdkVersion` in your `build.gradle` or `AndroidManifest.xml` files.
If your code is **deliberately** accessing newer APIs, and you have ensured (e.g. with conditional execution) that this code will only ever be called on a supported platform, then you can annotate your class or method with the `@TargetApi` annotation specifying the local minimum SDK to apply, such as `@TargetApi(11)`, such that this check considers 11 rather than your manifest file's minimum SDK as the required API level." errorLine1=" int layoutDirection = component.isLayoutRTL() ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java" line="202" column="55"/> </issue> <issue id="InlinedApi" severity="Warning" message="Field requires API level 17 (current min is 14): `android.view.View#LAYOUT_DIRECTION_LTR`" category="Correctness" priority="6" summary="Using inlined constants on older versions" explanation="This check scans through all the Android API field references in the application and flags certain constants, such as static final integers and Strings, which were introduced in later versions. These will actually be copied into the class files rather than being referenced, which means that the value is available even when running on older devices. In some cases that's fine, and in other cases it can result in a runtime crash or incorrect behavior. It depends on the context, so consider the code carefully and decide whether it's safe and can be suppressed or whether the code needs to be guarded.

If you really want to use this API and don't need to support older devices just set the `minSdkVersion` in your `build.gradle` or `AndroidManifest.xml` files.
If your code is **deliberately** accessing newer APIs, and you have ensured (e.g. with conditional execution) that this code will only ever be called on a supported platform, then you can annotate your class or method with the `@TargetApi` annotation specifying the local minimum SDK to apply, such as `@TargetApi(11)`, such that this check considers 11 rather than your manifest file's minimum SDK as the required API level." errorLine1=" int layoutDirection = component.isLayoutRTL() ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java" line="422" column="83"/> </issue> <issue id="InlinedApi" severity="Warning" message="Field requires API level 17 (current min is 14): `android.view.View#LAYOUT_DIRECTION_RTL`" category="Correctness" priority="6" summary="Using inlined constants on older versions" explanation="This check scans through all the Android API field references in the application and flags certain constants, such as static final integers and Strings, which were introduced in later versions. These will actually be copied into the class files rather than being referenced, which means that the value is available even when running on older devices. In some cases that's fine, and in other cases it can result in a runtime crash or incorrect behavior. It depends on the context, so consider the code carefully and decide whether it's safe and can be suppressed or whether the code needs to be guarded.

If you really want to use this API and don't need to support older devices just set the `minSdkVersion` in your `build.gradle` or `AndroidManifest.xml` files.
If your code is **deliberately** accessing newer APIs, and you have ensured (e.g. with conditional execution) that this code will only ever be called on a supported platform, then you can annotate your class or method with the `@TargetApi` annotation specifying the local minimum SDK to apply, such as `@TargetApi(11)`, such that this check considers 11 rather than your manifest file's minimum SDK as the required API level." errorLine1=" int layoutDirection = component.isLayoutRTL() ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java" line="422" column="55"/> </issue> <issue id="MissingDefaultResource" severity="Fatal" message="The bool "weex_is_right_to_left" in values-ldltr has no declaration in the base `values` folder; this can lead to crashes when the resource is queried in a configuration that does not match this qualifier" category="Correctness" priority="6" summary="Missing Default" explanation="If a resource is only defined in folders with qualifiers like `-land` or `-en`, and there is no default declaration in the base folder (`layout` or `values` etc), then the app will crash if that resource is accessed on a device where the device is in a configuration missing the given qualifier.

As a special case, drawables do not have to be specified in the base folder; if there is a match in a density folder (such as `drawable-mdpi`) that image will be used and scaled. Note however that if you only specify a drawable in a folder like `drawable-en-hdpi`, the app will crash in non-English locales.

There may be scenarios where you have a resource, such as a `-fr` drawable, which is only referenced from some other resource with the same qualifiers (such as a `-fr` style), which itself has safe fallbacks. However, this still makes it possible for somebody to accidentally reference the drawable and crash, so it is safer to create a default dummy fallback in the base folder. Alternatively, you can suppress the issue by adding `tools:ignore="MissingDefaultResource"` on the element.

(This scenario frequently happens with string translations, where you might delete code and the corresponding resources, but forget to delete a translation. There is a dedicated issue id for that scenario, with the id `ExtraTranslation`.)" errorLine1=" <bool name="weex_is_right_to_left">false</bool>" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/res/values-ldltr/isrtl.xml" line="23" column="11"/> </issue> <issue id="MissingDefaultResource" severity="Fatal" message="The bool "weex_is_right_to_left" in values-ldrtl has no declaration in the base `values` folder; this can lead to crashes when the resource is queried in a configuration that does not match this qualifier" category="Correctness" priority="6" summary="Missing Default" explanation="If a resource is only defined in folders with qualifiers like `-land` or `-en`, and there is no default declaration in the base folder (`layout` or `values` etc), then the app will crash if that resource is accessed on a device where the device is in a configuration missing the given qualifier.

As a special case, drawables do not have to be specified in the base folder; if there is a match in a density folder (such as `drawable-mdpi`) that image will be used and scaled. Note however that if you only specify a drawable in a folder like `drawable-en-hdpi`, the app will crash in non-English locales.

There may be scenarios where you have a resource, such as a `-fr` drawable, which is only referenced from some other resource with the same qualifiers (such as a `-fr` style), which itself has safe fallbacks. However, this still makes it possible for somebody to accidentally reference the drawable and crash, so it is safer to create a default dummy fallback in the base folder. Alternatively, you can suppress the issue by adding `tools:ignore="MissingDefaultResource"` on the element.

(This scenario frequently happens with string translations, where you might delete code and the corresponding resources, but forget to delete a translation. There is a dedicated issue id for that scenario, with the id `ExtraTranslation`.)" errorLine1=" <bool name="weex_is_right_to_left">true</bool>" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/res/values-ldrtl/istrtl.xml" line="23" column="11"/> </issue> <issue id="NewApi" severity="Error" message="Call requires API level 21 (current min is 14): new android.widget.FrameLayout" category="Correctness" priority="6" summary="Calling new methods on older versions" explanation="This check scans through all the Android API calls in the application and warns about any calls that are not available on **all** versions targeted by this application (according to its minimum SDK attribute in the manifest).

If you really want to use this API and don't need to support older devices just set the `minSdkVersion` in your `build.gradle` or `AndroidManifest.xml` files.

If your code is **deliberately** accessing newer APIs, and you have ensured (e.g. with conditional execution) that this code will only ever be called on a supported platform, then you can annotate your class or method with the `@TargetApi` annotation specifying the local minimum SDK to apply, such as `@TargetApi(11)`, such that this check considers 11 rather than your manifest file's minimum SDK as the required API level.

If you are deliberately setting `android:` attributes in style definitions, make sure you place this in a `values-v`*NN* folder in order to avoid running into runtime conflicts on certain devices where manufacturers have added custom attributes whose ids conflict with the new ones on later platforms.

Similarly, you can use tools:targetApi="11" in an XML file to indicate that the element will only be inflated in an adequate context." errorLine1=" super(context, attrs, defStyleAttr, defStyleRes);" errorLine2=" ~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/render/WXAbstractRenderContainer.java" line="50" column="9"/> </issue> <issue id="SdCardPath" severity="Warning" message="Do not hardcode "`/data/`"; use `Context.getFilesDir().getPath()` instead" category="Correctness" priority="6" summary="Hardcoded reference to `/sdcard`" explanation="Your code should not reference the `/sdcard` path directly; instead use `Environment.getExternalStorageDirectory().getPath()`.

Similarly, do not reference the `/data/data/` path directly; it can vary in multi-user scenarios. Instead, use `Context.getFilesDir().getPath()`." url="http://developer.android.com/guide/topics/data/data-storage.html#filesExternal" urls="http://developer.android.com/guide/topics/data/data-storage.html#filesExternal" errorLine1=" String toPath = "/data/data/" + pkgName + dirName;" errorLine2=" ~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java" line="297" column="27"/> </issue> <issue id="SdCardPath" severity="Warning" message="Do not hardcode "`/data/`"; use `Context.getFilesDir().getPath()` instead" category="Correctness" priority="6" summary="Hardcoded reference to `/sdcard`" explanation="Your code should not reference the `/sdcard` path directly; instead use `Environment.getExternalStorageDirectory().getPath()`.

Similarly, do not reference the `/data/data/` path directly; it can vary in multi-user scenarios. Instead, use `Context.getFilesDir().getPath()`." url="http://developer.android.com/guide/topics/data/data-storage.html#filesExternal" urls="http://developer.android.com/guide/topics/data/data-storage.html#filesExternal" errorLine1=" String path = "/data/data/" + pkgName + "/lib";" errorLine2=" ~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java" line="257" column="21"/> </issue> <issue id="SdCardPath" severity="Warning" message="Do not hardcode "`/data/`"; use `Context.getFilesDir().getPath()` instead" category="Correctness" priority="6" summary="Hardcoded reference to `/sdcard`" explanation="Your code should not reference the `/sdcard` path directly; instead use `Environment.getExternalStorageDirectory().getPath()`.

Similarly, do not reference the `/data/data/` path directly; it can vary in multi-user scenarios. Instead, use `Context.getFilesDir().getPath()`." url="http://developer.android.com/guide/topics/data/data-storage.html#filesExternal" urls="http://developer.android.com/guide/topics/data/data-storage.html#filesExternal" errorLine1=" String path = "/data/data/" + context.getPackageName() + "/files";" errorLine2=" ~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java" line="418" column="19"/> </issue> <issue id="ShowToast" severity="Warning" message="Toast created but not shown: did you forget to call `show()` ?" category="Correctness" priority="6" summary="Toast created but not shown" explanation="`Toast.makeText()` creates a `Toast` but does **not** show it. You must call `show()` on the resulting object to actually make the `Toast` appear." errorLine1=" toast = Toast.makeText(mWXSDKInstance.getContext(), message, duration);" errorLine2=" ~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/module/WXModalUIModule.java" line="90" column="15"/> </issue> <issue id="SimpleDateFormat" severity="Warning" message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates." category="Correctness" priority="6" summary="Implied locale in date format" explanation="Almost all callers should use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()` to get a ready-made instance of SimpleDateFormat suitable for the user's locale. The main reason you'd create an instance this class directly is because you need to format/parse a specific machine-readable format, in which case you almost certainly want to explicitly ask for US to ensure that you get ASCII digits (rather than, say, Arabic digits).

Therefore, you should either use the form of the SimpleDateFormat constructor where you pass in an explicit locale, such as Locale.US, or use one of the get instance methods, or suppress this error if really know what you are doing." url="http://developer.android.com/reference/java/text/SimpleDateFormat.html" urls="http://developer.android.com/reference/java/text/SimpleDateFormat.html" errorLine1=" DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java" line="937" column="25"/> </issue> <issue id="AppCompatCustomView" severity="Error" message="This custom view should extend `android.support.v7.widget.AppCompatImageView` instead" category="Correctness" priority="4" summary="Appcompat Custom Widgets" explanation="In order to support features such as tinting, the appcompat library will automatically load special appcompat replacements for the builtin widgets. However, this does not work for your own custom views.

Instead of extending the `android.widget` classes directly, you should instead extend one of the delegate classes in `android.support.v7.widget.AppCompat`." errorLine1="public class CircleProgressBar extends ImageView {" errorLine2=" ~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/refresh/circlebar/CircleProgressBar.java" line="38" column="40"/> </issue> <issue id="AppCompatCustomView" severity="Error" message="This custom view should extend `android.support.v7.widget.AppCompatEditText` instead" category="Correctness" priority="4" summary="Appcompat Custom Widgets" explanation="In order to support features such as tinting, the appcompat library will automatically load special appcompat replacements for the builtin widgets. However, this does not work for your own custom views.

Instead of extending the `android.widget` classes directly, you should instead extend one of the delegate classes in `android.support.v7.widget.AppCompat`." errorLine1="public class WXEditText extends EditText implements WXGestureObservable {" errorLine2=" ~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXEditText.java" line="36" column="33"/> </issue> <issue id="AppCompatCustomView" severity="Error" message="This custom view should extend `android.support.v7.widget.AppCompatImageView` instead" category="Correctness" priority="4" summary="Appcompat Custom Widgets" explanation="In order to support features such as tinting, the appcompat library will automatically load special appcompat replacements for the builtin widgets. However, this does not work for your own custom views.

Instead of extending the `android.widget` classes directly, you should instead extend one of the delegate classes in `android.support.v7.widget.AppCompat`." errorLine1="public class WXImageView extends ImageView implements WXGestureObservable," errorLine2=" ~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXImageView.java" line="42" column="34"/> </issue> <issue id="GradleOverrides" severity="Warning" message="This `versionCode` value (`1`) is not used; it is always overridden by the value specified in the Gradle build script (`1`)" category="Correctness" priority="4" summary="Value overridden by Gradle build script" explanation="The value of (for example) `minSdkVersion` is only used if it is not specified in the `build.gradle` build scripts. When specified in the Gradle build scripts, the manifest value is ignored and can be misleading, so should be removed to avoid ambiguity." errorLine1=" android:versionCode="1"" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/AndroidManifest.xml" line="22" column="11"/> </issue> <issue id="GradleOverrides" severity="Warning" message="This `versionName` value (`1.0`) is not used; it is always overridden by the value specified in the Gradle build script (`0.26.0.1`)" category="Correctness" priority="4" summary="Value overridden by Gradle build script" explanation="The value of (for example) `minSdkVersion` is only used if it is not specified in the `build.gradle` build scripts. When specified in the Gradle build scripts, the manifest value is ignored and can be misleading, so should be removed to avoid ambiguity." errorLine1=" android:versionName="1.0">" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/AndroidManifest.xml" line="23" column="11"/> </issue> <issue id="AddJavascriptInterface" severity="Warning" message="`WebView.addJavascriptInterface` should not be called with minSdkVersion < 17 for security reasons: JavaScript can use reflection to manipulate application" category="Security" priority="9" summary="addJavascriptInterface Called" explanation="For applications built for API levels below 17, `WebView#addJavascriptInterface` presents a security hazard as JavaScript on the target web page has the ability to use reflection to access the injected object's public fields and thus manipulate the host application in unintended ways." url="https://labs.mwrinfosecurity.com/blog/2013/09/24/webview-addjavascriptinterface-remote-code-execution/" urls="https://labs.mwrinfosecurity.com/blog/2013/09/24/webview-addjavascriptinterface-remote-code-execution/" errorLine1=" wv.addJavascriptInterface(new Object() {" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXWebView.java" line="318" column="16"/> </issue> <issue id="HardwareIds" severity="Warning" message="Using `getDeviceId` to get device identifiers is not recommended." category="Security" priority="6" summary="Hardware Id Usage" explanation="Using these device identifiers is not recommended other than for high value fraud prevention and advanced telephony use-cases. For advertising use-cases, use `AdvertisingIdClient$Info#getId` and for analytics, use `InstanceId#getId`." url="https://developer.android.com/training/articles/user-data-ids.html" urls="https://developer.android.com/training/articles/user-data-ids.html" errorLine1=" return sApplication == null ? "" : ((TelephonyManager) sApplication" errorLine2=" ^"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java" line="400" column="40"/> </issue> <issue id="SetJavaScriptEnabled" severity="Warning" message="Using `setJavaScriptEnabled` can introduce XSS vulnerabilities into your application, review carefully." category="Security" priority="6" summary="Using `setJavaScriptEnabled`" explanation="Your code should not invoke `setJavaScriptEnabled` if you are not sure that your app really requires JavaScript support." url="http://developer.android.com/guide/practices/security.html" urls="http://developer.android.com/guide/practices/security.html" errorLine1=" settings.setJavaScriptEnabled(true);" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXWebView.java" line="215" column="9"/> </issue> <issue id="UnsafeDynamicallyLoadedCode" severity="Warning" message="Dynamically loading code using `load` is risky, please use `loadLibrary` instead when possible" category="Security" priority="4" summary="`load` used to dynamically load code" explanation="Dynamically loading code from locations other than the application's library directory or the Android platform's built-in library directories is dangerous, as there is an increased risk that the code could have been tampered with. Applications should use `loadLibrary` when possible, which provides increased assurance that libraries are loaded from one of these safer locations. Application developers should use the features of their development environment to place application native libraries into the lib directory of their compiled APKs." errorLine1=" System.load(_targetSoFile(libName, version));" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java" line="469" column="11"/> </issue> <issue id="DrawAllocation" severity="Warning" message="Avoid object allocations during draw/layout operations (preallocate and reuse instead)" category="Performance" priority="9" summary="Memory allocations within drawing code" explanation="You should avoid allocating objects during a drawing or layout operation. These are called frequently, so a smooth UI can be interrupted by garbage collection pauses caused by the object allocations.

The way this is generally handled is to allocate the needed objects up front and to reuse them for each drawing operation.

Some methods allocate memory on your behalf (such as `Bitmap.create`), and these should be handled in the same way." errorLine1=" mBgCircle = new ShapeDrawable(new OvalShape());" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/refresh/circlebar/CircleProgressBar.java" line="144" column="21"/> </issue> <issue id="DrawAllocation" severity="Warning" message="Avoid object allocations during draw/layout operations (preallocate and reuse instead)" category="Performance" priority="9" summary="Memory allocations within drawing code" explanation="You should avoid allocating objects during a drawing or layout operation. These are called frequently, so a smooth UI can be interrupted by garbage collection pauses caused by the object allocations.

The way this is generally handled is to allocate the needed objects up front and to reuse them for each drawing operation.

Some methods allocate memory on your behalf (such as `Bitmap.create`), and these should be handled in the same way." errorLine1=" mBgCircle = new ShapeDrawable(new OvalShape());" errorLine2=" ~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/refresh/circlebar/CircleProgressBar.java" line="144" column="39"/> </issue> <issue id="DrawAllocation" severity="Warning" message="Avoid object allocations during draw/layout operations (preallocate and reuse instead)" category="Performance" priority="9" summary="Memory allocations within drawing code" explanation="You should avoid allocating objects during a drawing or layout operation. These are called frequently, so a smooth UI can be interrupted by garbage collection pauses caused by the object allocations.

The way this is generally handled is to allocate the needed objects up front and to reuse them for each drawing operation.

Some methods allocate memory on your behalf (such as `Bitmap.create`), and these should be handled in the same way." errorLine1=" OvalShape oval = new OvalShadow(mShadowRadius, mDiameter - mShadowRadius * 2);" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/refresh/circlebar/CircleProgressBar.java" line="147" column="26"/> </issue> <issue id="DrawAllocation" severity="Warning" message="Avoid object allocations during draw/layout operations (preallocate and reuse instead)" category="Performance" priority="9" summary="Memory allocations within drawing code" explanation="You should avoid allocating objects during a drawing or layout operation. These are called frequently, so a smooth UI can be interrupted by garbage collection pauses caused by the object allocations.

The way this is generally handled is to allocate the needed objects up front and to reuse them for each drawing operation.

Some methods allocate memory on your behalf (such as `Bitmap.create`), and these should be handled in the same way." errorLine1=" mBgCircle = new ShapeDrawable(oval);" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/refresh/circlebar/CircleProgressBar.java" line="148" column="21"/> </issue> <issue id="ObsoleteSdkInt" severity="Warning" message="Unnecessary; SDK_INT is never < 14" category="Performance" priority="6" summary="Obsolete SDK_INT Version Check" explanation="This check flags version checks that are not necessary, because the `minSdkVersion` (or surrounding known API level) is already at least as high as the version checked for.

Similarly, it also looks for resources in `-vNN` folders, such as `values-v14` where the version qualifier is less than or equal to the `minSdkVersion`, where the contents should be merged into the best folder." errorLine1=" if (Build.VERSION.SDK_INT < 14) {" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/refresh/core/WXSwipeLayout.java" line="699" column="9"/> </issue> <issue id="ObsoleteSdkInt" severity="Warning" message="Unnecessary; SDK_INT is never < 14" category="Performance" priority="6" summary="Obsolete SDK_INT Version Check" explanation="This check flags version checks that are not necessary, because the `minSdkVersion` (or surrounding known API level) is already at least as high as the version checked for.

Similarly, it also looks for resources in `-vNN` folders, such as `values-v14` where the version qualifier is less than or equal to the `minSdkVersion`, where the contents should be merged into the best folder." errorLine1=" if (Build.VERSION.SDK_INT < 14) {" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/refresh/core/WXSwipeLayout.java" line="721" column="9"/> </issue> <issue id="StaticFieldLeak" severity="Warning" message="Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)" category="Performance" priority="6" summary="Static Field Leaks" explanation="A static field will leak contexts.

Non-static inner classes have an implicit reference to their outer class. If that outer class is for example a `Fragment` or `Activity`, then this reference means that the long-running handler/loader/task will hold a reference to the activity which prevents it from getting garbage collected.

Similarly, direct field references to activities and fragments from these longer running instances can cause leaks.

ViewModel classes should never point to Views or non-application Contexts." errorLine1=" static Context mContext = null;" errorLine2=" ~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java" line="79" column="3"/> </issue> <issue id="UseSparseArrays" severity="Warning" message="Use `new SparseIntArray(...)` instead for better performance" category="Performance" priority="4" summary="HashMap can be replaced with SparseArray" explanation="For maps where the keys are of type integer, it's typically more efficient to use the Android `SparseArray` API. This check identifies scenarios where you might want to consider using `SparseArray` instead of `HashMap` for better performance.

This is **particularly** useful when the value types are primitives like ints, where you can use `SparseIntArray` and avoid auto-boxing the values from `int` to `Integer`.

If you need to construct a `HashMap` because you need to call an API outside of your control which requires a `Map`, you can suppress this warning using for example the `@SuppressLint` annotation." errorLine1=" antiIntAutoBoxing = new SparseArray<>();" errorLine2=" ~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java" line="66" column="25"/> </issue> <issue id="UseValueOf" severity="Warning" message="Use `Double.valueOf(((Integer) object).intValue())` instead" category="Performance" priority="4" summary="Should use `valueOf` instead of `new`" explanation="You should not call the constructor for wrapper classes directly, such as`new Integer(42)`. Instead, call the `valueOf` factory method, such as `Integer.valueOf(42)`. This will typically use less memory because common integers such as 0 and 1 will share a single instance." errorLine1=" data = new Double(((Integer) object).intValue());" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/bridge/WXJSObject.java" line="57" column="20"/> </issue> <issue id="UseValueOf" severity="Warning" message="Use `Double.valueOf(((Float) object).intValue())` instead" category="Performance" priority="4" summary="Should use `valueOf` instead of `new`" explanation="You should not call the constructor for wrapper classes directly, such as`new Integer(42)`. Instead, call the `valueOf` factory method, such as `Integer.valueOf(42)`. This will typically use less memory because common integers such as 0 and 1 will share a single instance." errorLine1=" data = new Double(((Float) object).intValue());" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/bridge/WXJSObject.java" line="62" column="20"/> </issue> <issue id="UseValueOf" severity="Warning" message="Use `Boolean.valueOf(isLayoutRTL())` instead" category="Performance" priority="4" summary="Should use `valueOf` instead of `new`" explanation="You should not call the constructor for wrapper classes directly, such as`new Integer(42)`. Instead, call the `valueOf` factory method, such as `Integer.valueOf(42)`. This will typically use less memory because common integers such as 0 and 1 will share a single instance." errorLine1=" mIslastDirectionRTL = new Boolean(isLayoutRTL());" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java" line="511" column="37"/> </issue> <issue id="IconLocation" severity="Warning" message="Found bitmap drawable `res/drawable/weex_error.png` in densityless folder" category="Usability:Icons" priority="5" summary="Image defined in density-independent drawable folder" explanation="The res/drawable folder is intended for density-independent graphics such as shapes defined in XML. For bitmaps, move it to `drawable-mdpi` and consider providing higher and lower resolution versions in `drawable-ldpi`, `drawable-hdpi` and `drawable-xhdpi`. If the icon **really** is density independent (for example a solid color) you can place it in `drawable-nodpi`." url="http://developer.android.com/guide/practices/screens_support.html" urls="http://developer.android.com/guide/practices/screens_support.html"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/res/drawable/weex_error.png"/> </issue> <issue id="ViewConstructor" severity="Warning" message="Custom view `BounceRecyclerView` is missing constructor used by tools: `(Context)` or `(Context,AttributeSet)` or `(Context,AttributeSet,int)`" category="Usability" priority="3" summary="Missing View constructors for XML inflation" explanation="Some layout tools (such as the Android layout editor) need to find a constructor with one of the following signatures:
* `View(Context context)`
* `View(Context context, AttributeSet attrs)`
* `View(Context context, AttributeSet attrs, int defStyle)`

If your custom view needs to perform initialization which does not apply when used in a layout editor, you can surround the given code with a check to see if `View#isInEditMode()` is false, since that method will return `false` at runtime but true within a user interface editor." errorLine1="public class BounceRecyclerView extends BaseBounceView<WXRecyclerView> implements ListComponentView,WXGestureObservable {" errorLine2=" ~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/refresh/wrapper/BounceRecyclerView.java" line="33" column="14"/> </issue> <issue id="ViewConstructor" severity="Warning" message="Custom view `BounceScrollerView` is missing constructor used by tools: `(Context)` or `(Context,AttributeSet)` or `(Context,AttributeSet,int)`" category="Usability" priority="3" summary="Missing View constructors for XML inflation" explanation="Some layout tools (such as the Android layout editor) need to find a constructor with one of the following signatures:
* `View(Context context)`
* `View(Context context, AttributeSet attrs)`
* `View(Context context, AttributeSet attrs, int defStyle)`

If your custom view needs to perform initialization which does not apply when used in a layout editor, you can surround the given code with a check to see if `View#isInEditMode()` is false, since that method will return `false` at runtime but true within a user interface editor." errorLine1="public class BounceScrollerView extends BaseBounceView<WXScrollView> {" errorLine2=" ~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/refresh/wrapper/BounceScrollerView.java" line="26" column="14"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="`onTouch` should call `View#performClick` when a click is detected" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouch(View v, MotionEvent event) {" errorLine2=" ~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java" line="941" column="28"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="`TouchActivePseudoListener#onTouch` should call `View#performClick` when a click is detected" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouch(View v, MotionEvent event) {" errorLine2=" ~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/pesudo/TouchActivePseudoListener.java" line="37" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view `WXCircleViewPager` overrides `onTouchEvent` but not `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouchEvent(MotionEvent ev) {" errorLine2=" ~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXCircleViewPager.java" line="154" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view `WXEditText` overrides `onTouchEvent` but not `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouchEvent(MotionEvent event) {" errorLine2=" ~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXEditText.java" line="69" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="`WXGesture#onTouch` should call `View#performClick` when a click is detected" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouch(View v, MotionEvent event) {" errorLine2=" ~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/gesture/WXGesture.java" line="211" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view `WXHorizontalScrollView` overrides `onTouchEvent` but not `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouchEvent(MotionEvent ev) {" errorLine2=" ~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXHorizontalScrollView.java" line="109" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view `WXImageView` overrides `onTouchEvent` but not `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouchEvent(MotionEvent event) {" errorLine2=" ~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXImageView.java" line="110" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view `WXRecyclerView` overrides `onTouchEvent` but not `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouchEvent(MotionEvent event) {" errorLine2=" ~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/listview/WXRecyclerView.java" line="92" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view `WXRichTextView` overrides `onTouchEvent` but not `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouchEvent(MotionEvent event) {" errorLine2=" ~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/richtext/WXRichTextView.java" line="41" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view `WXScrollView` overrides `onTouchEvent` but not `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouchEvent(MotionEvent ev) {" errorLine2=" ~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXScrollView.java" line="186" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view ``WXHorizontalScrollView`` has `setOnTouchListener` called on it but does not override `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" scrollView.setOnTouchListener(new View.OnTouchListener() {" errorLine2=" ^"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java" line="531" column="9"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="`onTouch` should call `View#performClick` when a click is detected" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouch(View v, MotionEvent event) {" errorLine2=" ~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java" line="533" column="26"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view ``WXCircleViewPager`` has `setOnTouchListener` called on it but does not override `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" mViewPager.setOnTouchListener(new View.OnTouchListener() {" errorLine2=" ^"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java" line="564" column="9"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="`onTouch` should call `View#performClick` when a click is detected" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouch(View v, MotionEvent event) {" errorLine2=" ~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java" line="566" column="26"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view ``WXCircleViewPager`` has `setOnTouchListener` called on it but does not override `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" mViewPager.setOnTouchListener(null);" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXSlider.java" line="571" column="9"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view `WXSwitchView` overrides `onTouchEvent` but not `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouchEvent(MotionEvent event) {" errorLine2=" ~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXSwitchView.java" line="50" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view `WXTextView` overrides `onTouchEvent` but not `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouchEvent(MotionEvent event) {" errorLine2=" ~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXTextView.java" line="69" column="18"/> </issue> <issue id="ClickableViewAccessibility" severity="Warning" message="Custom view `WXVideoView` overrides `onTouchEvent` but not `performClick`" category="Accessibility" priority="6" summary="Accessibility in Custom Views" explanation="If a `View` that overrides `onTouchEvent` or uses an `OnTouchListener` does not also implement `performClick` and call it when clicks are detected, the `View` may not handle accessibility actions properly. Logic handling the click actions should ideally be placed in `View#performClick` as some accessibility services invoke `performClick` when a click action should occur." errorLine1=" public boolean onTouchEvent(MotionEvent event) {" errorLine2=" ~~~~~~~~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/view/WXVideoView.java" line="68" column="18"/> </issue> <issue id="RtlHardcoded" severity="Warning" message="Use "`Gravity.END`" instead of "`Gravity.RIGHT`" to ensure correct behavior in right-to-left locales" category="Internationalization:Bidirectional Text" priority="5" summary="Using left/right instead of start/end attributes" explanation="Using `Gravity#LEFT` and `Gravity#RIGHT` can lead to problems when a layout is rendered in locales where text flows from right to left. Use `Gravity#START` and `Gravity#END` instead. Similarly, in XML `gravity` and `layout_gravity` attributes, use `start` rather than `left`.

For XML attributes such as paddingLeft and `layout_marginLeft`, use `paddingStart` and `layout_marginStart`. **NOTE**: If your `minSdkVersion` is less than 17, you should add **both** the older left/right attributes **as well as** the new start/right attributes. On older platforms, where RTL is not supported and the start/right attributes are unknown and therefore ignored, you need the older left/right attributes. There is a separate lint check which catches that type of error.

(Note: For `Gravity#LEFT` and `Gravity#START`, you can use these constants even when targeting older platforms, because the `start` bitmask is a superset of the `left` bitmask. Therefore, you can use `gravity="start"` rather than `gravity="left|start"`.)" errorLine1=" lp_frameLayout.gravity = Gravity.RIGHT | Gravity.TOP;" errorLine2=" ~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java" line="187" column="44"/> </issue> <issue id="RtlHardcoded" severity="Warning" message="Use "`Gravity.START`" instead of "`Gravity.LEFT`" to ensure correct behavior in right-to-left locales" category="Internationalization:Bidirectional Text" priority="5" summary="Using left/right instead of start/end attributes" explanation="Using `Gravity#LEFT` and `Gravity#RIGHT` can lead to problems when a layout is rendered in locales where text flows from right to left. Use `Gravity#START` and `Gravity#END` instead. Similarly, in XML `gravity` and `layout_gravity` attributes, use `start` rather than `left`.

For XML attributes such as paddingLeft and `layout_marginLeft`, use `paddingStart` and `layout_marginStart`. **NOTE**: If your `minSdkVersion` is less than 17, you should add **both** the older left/right attributes **as well as** the new start/right attributes. On older platforms, where RTL is not supported and the start/right attributes are unknown and therefore ignored, you need the older left/right attributes. There is a separate lint check which catches that type of error.

(Note: For `Gravity#LEFT` and `Gravity#START`, you can use these constants even when targeting older platforms, because the `start` bitmask is a superset of the `left` bitmask. Therefore, you can use `gravity="start"` rather than `gravity="left|start"`.)" errorLine1=" lp_frameLayout.gravity = Gravity.LEFT | Gravity.TOP;" errorLine2=" ~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java" line="190" column="44"/> </issue> <issue id="RtlHardcoded" severity="Warning" message="Use "`Gravity.START`" instead of "`Gravity.LEFT`" to ensure correct behavior in right-to-left locales" category="Internationalization:Bidirectional Text" priority="5" summary="Using left/right instead of start/end attributes" explanation="Using `Gravity#LEFT` and `Gravity#RIGHT` can lead to problems when a layout is rendered in locales where text flows from right to left. Use `Gravity#START` and `Gravity#END` instead. Similarly, in XML `gravity` and `layout_gravity` attributes, use `start` rather than `left`.

For XML attributes such as paddingLeft and `layout_marginLeft`, use `paddingStart` and `layout_marginStart`. **NOTE**: If your `minSdkVersion` is less than 17, you should add **both** the older left/right attributes **as well as** the new start/right attributes. On older platforms, where RTL is not supported and the start/right attributes are unknown and therefore ignored, you need the older left/right attributes. There is a separate lint check which catches that type of error.

(Note: For `Gravity#LEFT` and `Gravity#START`, you can use these constants even when targeting older platforms, because the `start` bitmask is a superset of the `left` bitmask. Therefore, you can use `gravity="start"` rather than `gravity="left|start"`.)" errorLine1=" lp_frameLayout.gravity = Gravity.LEFT | Gravity.TOP;" errorLine2=" ~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java" line="254" column="44"/> </issue> <issue id="RtlHardcoded" severity="Warning" message="Use "`Gravity.END`" instead of "`Gravity.RIGHT`" to ensure correct behavior in right-to-left locales" category="Internationalization:Bidirectional Text" priority="5" summary="Using left/right instead of start/end attributes" explanation="Using `Gravity#LEFT` and `Gravity#RIGHT` can lead to problems when a layout is rendered in locales where text flows from right to left. Use `Gravity#START` and `Gravity#END` instead. Similarly, in XML `gravity` and `layout_gravity` attributes, use `start` rather than `left`.

For XML attributes such as paddingLeft and `layout_marginLeft`, use `paddingStart` and `layout_marginStart`. **NOTE**: If your `minSdkVersion` is less than 17, you should add **both** the older left/right attributes **as well as** the new start/right attributes. On older platforms, where RTL is not supported and the start/right attributes are unknown and therefore ignored, you need the older left/right attributes. There is a separate lint check which catches that type of error.

(Note: For `Gravity#LEFT` and `Gravity#START`, you can use these constants even when targeting older platforms, because the `start` bitmask is a superset of the `left` bitmask. Therefore, you can use `gravity="start"` rather than `gravity="left|start"`.)" errorLine1=" lp_frameLayout.gravity = Gravity.RIGHT | Gravity.TOP;" errorLine2=" ~~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java" line="402" column="44"/> </issue> <issue id="RtlHardcoded" severity="Warning" message="Use "`Gravity.START`" instead of "`Gravity.LEFT`" to ensure correct behavior in right-to-left locales" category="Internationalization:Bidirectional Text" priority="5" summary="Using left/right instead of start/end attributes" explanation="Using `Gravity#LEFT` and `Gravity#RIGHT` can lead to problems when a layout is rendered in locales where text flows from right to left. Use `Gravity#START` and `Gravity#END` instead. Similarly, in XML `gravity` and `layout_gravity` attributes, use `start` rather than `left`.

For XML attributes such as paddingLeft and `layout_marginLeft`, use `paddingStart` and `layout_marginStart`. **NOTE**: If your `minSdkVersion` is less than 17, you should add **both** the older left/right attributes **as well as** the new start/right attributes. On older platforms, where RTL is not supported and the start/right attributes are unknown and therefore ignored, you need the older left/right attributes. There is a separate lint check which catches that type of error.

(Note: For `Gravity#LEFT` and `Gravity#START`, you can use these constants even when targeting older platforms, because the `start` bitmask is a superset of the `left` bitmask. Therefore, you can use `gravity="start"` rather than `gravity="left|start"`.)" errorLine1=" lp_frameLayout.gravity = Gravity.LEFT | Gravity.TOP;" errorLine2=" ~~~~"> <location file="/home/travis/build/apache/incubator-weex/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java" line="405" column="44"/> </issue> </issues> </td> </tr> <tr> <td>:warning:</td> <td>## AndroidLint Result</td> </tr> </tbody> </table> <p align="right"> Generated by :no_entry_sign: <a href="https://danger.systems/js">dangerJS</a> against 7be8783e5cbbf899a63730644d6f2e62c8b68a80 </p>
---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
