折腾:
【未解决】Android Studio中gradle编译rcjsta项目多个使用或覆盖了已过时的API等报错
期间,gradle编译报错:
> Task :RI:compileDebugJavaWithJavac 注: 某些输入文件使用或覆盖了已过时的 API。 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。 注: /Users/xxx/dev/xxx/RCS/rcsjta/RI/src/com/gsma/rcs/ri/messaging/geoloc/DisplayGeoloc.java使用了未经检查或不安全的操作。 注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。

去解决

但是找不到具体错误的位置。
那看看如何加上所说的
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
android studio 使用了未经检查或不安全的操作
去看看此处代码中是否有ArrayList类似写法
没有。
对于集合类,需要指定其类型。
后来有点看懂了:
代码右边有黄色标记

就表示:
警告类别的东西
最好去修改
而上面的:
mMapContactGeoloc = (HashMap<String, Geoloc>) getIntent() .getSerializableExtra(EXTRA_GEOLOC);
就是有警告
鼠标移动上去,看到提示:
Unchecked cast: 'java.io.Serializable' to 'java.util.HashMap<java.lang.String,com.gsma.services.rcs.Geoloc>'

Try to generify
More actions
点击More actions试试

算了。
还是去搜搜:
Try to generify
是啥意思
try to generify intellij
Generify 重构前:
public void method() { List list = new LinkedList(); list.add("string"); }
Generify 重构后:
public void method() { List<String> list = new LinkedList<String>(); list.add("string"); }
很明显就是之前的:
对于集合类,需要指定其类型。
即:
IntelliJ IDEA 尝试生成代码,从 Java 的角度来看,这是尽可能正确的。换句话说,每个上下文都引入了一些类型限制,重构会产生最好的类型,这与现有的上下文不矛盾。
不过:
【已解决】Android Studio中gradle编译的项目如何加参数:-Xlint:unchecked
确认就是此处:
/Users/xxx/dev/xxx/RCS/rcsjta/RI/src/com/gsma/rcs/ri/messaging/geoloc/DisplayGeoloc.java:91: 警告: [unchecked] 未经检查的转换 .getSerializableExtra(EXTRA_GEOLOC); ^ 需要: HashMap<String,Geoloc> 找到: Serializable

然后再去根据generify去试试:


点击 Preview

点击Do Refactor

好像没有任何变化。。。
然后就不太清楚,应该如何修改代码了。
对于此处代码:
mMapContactGeoloc = (HashMap<String, Geoloc>) getIntent() .getSerializableExtra(EXTRA_GEOLOC);
去找找代码逻辑中的EXTRA_GEOLOC
src/com/gsma/rcs/ri/messaging/geoloc/DisplayGeoloc.java
public final static String EXTRA_GEOLOC = "geoloc";
就只是字符串而已
然后再去看看
getSerializableExtra

看起来,Android库中有对应实现。
另外从其他地方看起来是:

src/com/gsma/rcs/ri/messaging/geoloc/EditGeoloc.java
private OnClickListener btnValidateListener = new OnClickListener() { public void onClick(View v) { 。。。 Geoloc geoloc = new Geoloc(mLocationEdit.getText().toString(), Double.parseDouble(lat), Double.parseDouble(lon), expiration, Float.parseFloat(acc)); Intent in = new Intent(); in.putExtra(EXTRA_GEOLOC, (Parcelable) geoloc);
-》看起来是,至少别处有多个具体的实现
把EXTRA_GEOLOC和对应的Geoloc类的实例放到extra参数中
供其他地方调用
所以,上述,强制转换:
(HashMap<String, Geoloc>)
逻辑上倒也没问题。
但是只是此处警告语法有问题
所以转去找找是否有其他更合法的写法
搜:
android getSerializableExtra
就看到提示有:

android getserializableextra cast
另外试了试:

Move initializer to constructor
结果这段代码,被移动到类的最开始了:

也不是我们希望的
且依旧被提示语法有问题
再试试勾选:
Generify Objects

结果:啥都没变。
没有生成要的,语法更好的代码。
尝试自己改改试试
android/content/Intent.java
/** * Retrieve extended data from the intent. * * @param name The name of the desired item. * * @return the value of an item that previously added with putExtra() * or null if no Serializable value was found. * * @see #putExtra(String, Serializable) */ public Serializable getSerializableExtra(String name) { return mExtras == null ? null : mExtras.getSerializable(name); }
看到返回类型是:
String, Serializable
然后再去试试
import java.io.Serializable; HashMap<String, Serializable> para_geoloc = getIntent().getSerializableExtra(EXTRA_GEOLOC); mMapContactGeoloc = (HashMap<String, Geoloc>)para_geoloc;
结果语法错误:


去转换试试
HashMap<String, Serializable> para_geoloc = (HashMap<String, Serializable>) getIntent().getSerializableExtra(EXTRA_GEOLOC);
提示是:

和之前一样的
unchecked cast
那想到:
如何实现 checked cast?
android how do checked cast of intent
java – Application cannot be cast to android.app.Activity while checking permission – Stack Overflow
好像意思是:换Serializable为Parcelable 就可以 消除警告了?
此处没法转换,因为Serializable是内置的实现
不过试试getParcelableArrayListExtra能否用
不过搜:
EXTRA_GEOLOC
也才注意到,别处也有一些Parcelable相关的:
getParcelableExtra
src/com/gsma/rcs/ri/messaging/geoloc/EditGeoloc.java
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != RESULT_OK) { return; } switch (requestCode) { case REQUEST_CODE_SELECT_GEOLOC: Geoloc geoloc = data.getParcelableExtra(EXTRA_GEOLOC);
src/com/gsma/rcs/ri/sharing/geoloc/InitiateGeolocSharing.java
public void onActivityResult(int requestCode, int resultCode, Intent data) { 。。。 /* Get selected geoloc */ mGeoloc = data.getParcelableExtra(EditGeoloc.EXTRA_GEOLOC);
不过另外才明白了,此处的是DisplayGeoloc.java
要在同一个文件内找对应的 put的地方:
src/com/gsma/rcs/ri/messaging/geoloc/DisplayGeoloc.java
public static void showContactOnMap(Context ctx, ContactId contact, Geoloc geoloc) { HashMap<String, Geoloc> mapContactGeoloc = new HashMap<>(); String displayName = RcsContactUtil.getInstance(ctx).getDisplayName(contact); mapContactGeoloc.put(displayName, geoloc); Intent intent = new Intent(ctx, DisplayGeoloc.class); intent.putExtra(DisplayGeoloc.EXTRA_GEOLOC, mapContactGeoloc); ctx.startActivity(intent); }
和:
public static void showContactsOnMap(Context ctx, Set<ContactId> contacts) { HashMap<String, Geoloc> mapContactGeoloc = new HashMap<>(); RcsContactUtil rcsContactUtil = RcsContactUtil.getInstance(ctx); for (ContactId contact : contacts) { Geoloc geoloc = getLastGeoloc(ctx, contact); if (geoloc != null) { mapContactGeoloc.put(rcsContactUtil.getDisplayName(contact), geoloc); } } Geoloc myGeoloc = getMyLastGeoloc(ctx); if (myGeoloc != null) { mapContactGeoloc.put(ctx.getString(R.string.label_me), myGeoloc); } if (mapContactGeoloc.isEmpty()) { Utils.displayLongToast(ctx, ctx.getString(R.string.label_geoloc_not_found)); return; } Intent intent = new Intent(ctx, DisplayGeoloc.class); intent.putExtra(DisplayGeoloc.EXTRA_GEOLOC, mapContactGeoloc); ctx.startActivity(intent); }

改为:
mMapContactGeoloc = (HashMap<String, Geoloc>) getIntent().getParcelableExtra(EXTRA_GEOLOC);
然后提示变了:

Unchecked cast: 'android.os.Parcelable' to 'java.util.HashMap<java.lang.String,com.gsma.services.rcs.Geoloc>' Casting 'getIntent().getParcelableExtra(...)' to 'HashMap<String, Geoloc>' is redundant
好像是多余的,那就去掉看看:
mMapContactGeoloc = getIntent().getParcelableExtra(EXTRA_GEOLOC);

是没警告了。
但是参考的帖子
人家改为Parcelable的前提是:对应内部实现PictureInfo的implements从Serializable改为了Parcelable
此处,需要去搞清楚,能否这么
直接改getSerializableExtra为getParcelableExtra
会不会导致其他异常?
getSerializableExtra getParcelableExtra
果然是:
先要用:
Bundle.putParcelable(Key,Obj)
之后,后续才能用对应的:
getParcelableExtra
的
否则应该只能是:
Bundle.putSerializable(Key,Obj)
然后后续用:
getSerializableExtra
而此处的值是:
HashMap<String, Geoloc>
不知道是否支持?
难道是内部的HashMap 内置已至支持Parcelable?
public class Intent extends Object implements Parcelable, Cloneable
不过本身Intent是,即实现了Parcelable,又实现了Cloneable
Retrieve extended data from the intent. | |
Retrieve extended data from the intent. | |
Retrieve extended data from the intent. |
getParcelableExtra
Added in API level 1
public T getParcelableExtra (String name)
Retrieve extended data from the intent.
Parameters
name
String: The name of the desired item.
Returns
T
the value of an item previously added with putExtra(), or null if no Parcelable value was found.
See also:
putExtra(String, Parcelable)
返回之前通过 putExtra添加的值
那么对应着之前的:
intent.putExtra(DisplayGeoloc.EXTRA_GEOLOC, mapContactGeoloc);
或:
intent.putExtra(DisplayGeoloc.EXTRA_GEOLOC, mapContactGeoloc);
如果是这样的话,倒是上述代码,也没问题,可以这么改。
也是类似的说法,对应的用于演示的类CustomClass,分别要实现Serializable或Parcelable
然后分别用:getSerializableExtra 或 getParcelableExtra
此处突然有点点明白,或许上述的:
HashMap<String, Geoloc>
其中整个作为整体,要支持Parcelable 就可以这么写
那么String自带支持
那么去看看:此处的Geoloc
src/main/java/com/gsma/services/rcs/Geoloc.java
public class Geoloc implements Parcelable, Serializable {
好了,即支持Serializable,也支持我们希望的Parcelable
所以就是可以这么写:
mMapContactGeoloc = getIntent().getParcelableExtra(EXTRA_GEOLOC);
估计是没问题的。
然后后续去编译和运行,希望此处代码不会报错,可以正常传递值过来。
有待后续验证。
编译没问题。
【总结】
对于最初代码:
mMapContactGeoloc = (HashMap<String, Geoloc>) getIntent() .getSerializableExtra(EXTRA_GEOLOC);
编译报错:
注: 某些输入文件使用或覆盖了已过时的 API。 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
而去加了参数:
build.gradle
allprojects { ... gradle.projectsEvaluated { tasks.withType(JavaCompile) { options.compilerArgs << "-Xlint:unchecked" } } }
后,可以确定就是上面代码报错。
且Android Studio中也能看到,该段代码背景土黄色,表示有问题。
鼠标移动上去提示:
Unchecked cast: 'java.io.Serializable' to 'java.util.HashMap<java.lang.String,com.gsma.services.rcs.Geoloc>'
根据提示:
Try to generify
去
Refactor
结果并没有重构。
通过研究代码,发现是:
此处getSerializableExtra所返回的值的类型,的确是,此处要强制cast转换的:
HashMap<String, Geoloc>
且:类Geoloc的源码是:
public class Geoloc implements Parcelable, Serializable {
即:不仅实现了Serializable,还实现了Parcelable
所以,为了消除代码警告,可以去改为Parcelable的写法:
mMapContactGeoloc = getIntent().getParcelableExtra(EXTRA_GEOLOC);
即可消除警告。
注:
关于Serializable和Parcelable的区别,和为何把Serializable换成Parcelable,是因为:
【整理】Android中的数据传递和序列化:Serializable和Parcelable
关于接口getParcelableExtra,可以参考:
public T getParcelableExtra (String name)
转载请注明:在路上 » 【已解决】rcsjta项目编译出错:DisplayGeoloc.java使用了未经检查或不安全的操作