利用Android Studio快速搭建App

大家好,我是烤鸭:

给大家分享一个简单的用Android Studio快速搭建app

工具:

 Android Studio 64位 专业版

插件:

  Datepicker Timepicker okhttp

实现需求:

 界面上选择时间,发get/post请求到后台,获取选择的时间。


1.修改AndroidManifest.xml文件


 其中可以修改app样式,app图标,进入app的最先执行哪个activity,

最重要的!!!

创建的activity一定要在这里注册。

项目名/app/build.gradle中添加依赖,这里贴一下我用到的。

apply plugin: 'com.android.application'android {compileSdkVersion 26defaultConfig {applicationId "com.example.gmwang.washapplication"minSdkVersion 15targetSdkVersion 26versionCode 1versionName "1.0"testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'com.android.support:appcompat-v7:26.1.0'implementation 'com.android.support.constraint:constraint-layout:1.0.2'testImplementation 'junit:junit:4.12'androidTestImplementation 'com.android.support.test:runner:1.0.1'androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.7'compile 'com.squareup.okhttp3:okhttp:3.3.0'compile 'com.android.support:design:+'compile 'com.zhy:okhttputils:2.6.1'compile 'com.alibaba:fastjson:1.2.7'
}


2.创建Splash页面

 可以看到上面我设置的最先跳转的activity是SplashActivity,这是一个过渡页面,一般app都是有一个页面或者是广告,等几秒再进入app的首页。

创建SplashActivity

package com.example.gmwang.washapplication;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;import java.util.Timer;
import java.util.TimerTask;/*** Created by gmwang on 2017/11/15.*/public class SplashActivity extends Activity {Timer timer;Message message;private Handler handler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case 1:if (timer != null) {timer.cancel();timer = null;}Intent i = new Intent(SplashActivity.this,WashViewActivity.class);startActivity(i);break;default:break;}}};@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_spalsh);timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {message = new Message();message.what = 1;handler.sendMessage(message);}}, 3000, 3000);}
}

先说这一行:

setContentView(R.layout.activity_spalsh);

需要创建activity_spalsh的layout,就是页面。

这里就是画了一个简单的页面,里边放了一张图。


代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#333333"><pl.droidsonroids.gif.GifImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/wash"/>
</LinearLayout>

再说这一行:

Intent i = new Intent(SplashActivity.this,WashViewActivity.class);

就是从这个页面3秒之后,跳转到哪个acticity。


3.创建WashViewActivity页面

这个页面就稍微复杂点,需要有picker插件和okhttp。

先把代码贴出来:

package com.example.gmwang.washapplication;import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;import com.alibaba.fastjson.JSONObject;
import com.example.gmwang.washapplication.utils.Constants;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;import java.util.Calendar;import okhttp3.Call;/*** Created by gmwang on 2017/11/24.*/public class WashViewActivity extends Activity {private TextView tvShowDialog;private TextView timeDialog;private Calendar cal;private int year, month, day;private int hour, minute;private String dateString = "0000";private String timeString = "0000";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_washview);Button recordButton = findViewById(R.id.recordId);Button recordListButton = findViewById(R.id.recordList);tvShowDialog = (TextView) findViewById(R.id.tvShowDialog);timeDialog = (TextView) findViewById(R.id.timeDialog);//获取当前日期getDate();tvShowDialog.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.tvShowDialog:DatePickerDialog.OnDateSetListener listener = new DatePickerDialog.OnDateSetListener() {@Overridepublic void onDateSet(DatePicker arg0, int year, int month, int day) {dateString = year + "-" + (++month) + "-" + day;tvShowDialog.setText(dateString);      //将选择的日期显示到TextView中,因为之前获取month直接使用,所以不需要+1,这个地方需要显示,所以+1}};DatePickerDialog dialog = new DatePickerDialog(WashViewActivity.this, 0, listener, year, month, day);//后边三个参数为显示dialog时默认的日期,月份从0开始,0-11对应1-12个月dialog.show();break;default:break;}}});timeDialog.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.timeDialog:TimePickerDialog.OnTimeSetListener listener = new TimePickerDialog.OnTimeSetListener() {@Overridepublic void onTimeSet(TimePicker timePicker, int hour, int minute) {timeString = hour + ":"+minute;timeDialog.setText(timeString);}};TimePickerDialog dialog = new TimePickerDialog(WashViewActivity.this, 0, listener, hour, minute,true);dialog.show();break;default:break;}}});recordButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Log.e("recordButton",dateString);if(TextUtils.isEmpty(tvShowDialog.getText())){Toast.makeText(getApplicationContext(), "请先选择日期!!!!!!", Toast.LENGTH_LONG).show();return ;}if(TextUtils.isEmpty(timeDialog.getText())){Toast.makeText(getApplicationContext(), "请先选择时间!!!!!!", Toast.LENGTH_LONG).show();return ;}String url = Constants.url+"addRecord";StringBuffer sb = new StringBuffer();OkHttpUtils.get().url(url).addParams("cuuid","66666").addParams("washDate", dateString).addParams("washTime",timeString).build().execute(new StringCallback() {@Overridepublic void onError(Call call, Exception e, int id) {Log.e("onError:", e.toString());}@Overridepublic void onResponse(String response, int id) {Log.e("onResponse:", response);JSONObject responseJson = (JSONObject) JSONObject.parse(response);String code = responseJson.getString("code");String message = responseJson.getString("message");//保存成功if("100".equals(responseJson.get("code"))){Toast.makeText(getApplicationContext(), code+","+responseJson.get("message"), Toast.LENGTH_LONG).show();}else{Toast.makeText(getApplicationContext(), code+","+responseJson.get("message"), Toast.LENGTH_LONG).show();}}});}});}//获取当前日期private void getDate() {cal = Calendar.getInstance();year = cal.get(Calendar.YEAR);       //获取年月日时分秒Log.i("wxy", "year" + year);month = cal.get(Calendar.MONTH);   //获取到的月份是从0开始计数day = cal.get(Calendar.DAY_OF_MONTH);hour = cal.get(Calendar.HOUR_OF_DAY);minute = cal.get(Calendar.MINUTE);}
}


代码有点多,我们一行一行看:

setContentView(R.layout.activity_washview);

跟上面一样,去画个页面activity_washview去,页面上有时间选择插件。

效果:


3.1 activity_washview代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.gmwang.washapplication.MainActivity"><RelativeLayoutandroid:id="@+id/rle1"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="76dp"><TextViewandroid:id="@+id/dateText"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_marginLeft="10dp"android:text="日期" /><EditTextandroid:id="@+id/tvShowDialog"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:layout_toRightOf="@+id/dateText"android:background="@drawable/dateshape"android:focusable="false" /></RelativeLayout><RelativeLayoutandroid:id="@+id/r_time"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="116dp"><TextViewandroid:id="@+id/timeText"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_marginLeft="10dp"android:text="时间" /><EditTextandroid:id="@+id/timeDialog"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:layout_toRightOf="@+id/timeText"android:background="@drawable/dateshape"android:focusable="false"/></RelativeLayout><RelativeLayoutandroid:id="@+id/rle2"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="156dp"></RelativeLayout><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_alignParentStart="true"android:layout_alignTop="@+id/rle1">><Buttonandroid:id="@+id/recordId"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="80dp"android:layout_marginTop="200dp"android:text="record"android:textColor="#f00"android:background="@drawable/button"/></RelativeLayout>
</RelativeLayout>

3.2 贴一下自定义样式,就是个边框,dateshape.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><stroke android:color="#000000"android:width="0.5dp"></stroke>
</shape>


3.3 关于textview和button

定义的textview和button都是根据id来找的。

比如:

private TextView tvShowDialog;

tvShowDialog = (TextView) findViewById(R.id.tvShowDialog);

这样就找到这个textView,就可以给他赋值或者其他操作了。button也是一样。


3.4 时间选择插件

DatePicker插件:

tvShowDialog.setOnClickListener 是选择后获取年/月/日/的

TimeDatePicker插件:

timeDialog.setOnClickListener 是选择后获取时/分/的


3.5 http请求

后面的按钮点击方法

recordButton.setOnClickListener,发送http请求,利用okhttp组件

可以看到这里的OkHttpUtils,贴一下代码

package com.zhy.http.okhttp;import com.zhy.http.okhttp.builder.GetBuilder;
import com.zhy.http.okhttp.builder.HeadBuilder;
import com.zhy.http.okhttp.builder.OtherRequestBuilder;
import com.zhy.http.okhttp.builder.PostFileBuilder;
import com.zhy.http.okhttp.builder.PostFormBuilder;
import com.zhy.http.okhttp.builder.PostStringBuilder;
import com.zhy.http.okhttp.callback.Callback;
import com.zhy.http.okhttp.request.RequestCall;
import com.zhy.http.okhttp.utils.Platform;import java.io.IOException;
import java.util.concurrent.Executor;import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Response;/*** Created by zhy on 15/8/17.*/
public class OkHttpUtils
{public static final long DEFAULT_MILLISECONDS = 10_000L;private volatile static OkHttpUtils mInstance;private OkHttpClient mOkHttpClient;private Platform mPlatform;public OkHttpUtils(OkHttpClient okHttpClient){if (okHttpClient == null){mOkHttpClient = new OkHttpClient();} else{mOkHttpClient = okHttpClient;}mPlatform = Platform.get();}public static OkHttpUtils initClient(OkHttpClient okHttpClient){if (mInstance == null){synchronized (OkHttpUtils.class){if (mInstance == null){mInstance = new OkHttpUtils(okHttpClient);}}}return mInstance;}public static OkHttpUtils getInstance(){return initClient(null);}public Executor getDelivery(){return mPlatform.defaultCallbackExecutor();}public OkHttpClient getOkHttpClient(){return mOkHttpClient;}public static GetBuilder get(){return new GetBuilder();}public static PostStringBuilder postString(){return new PostStringBuilder();}public static PostFileBuilder postFile(){return new PostFileBuilder();}public static PostFormBuilder post(){return new PostFormBuilder();}public static OtherRequestBuilder put(){return new OtherRequestBuilder(METHOD.PUT);}public static HeadBuilder head(){return new HeadBuilder();}public static OtherRequestBuilder delete(){return new OtherRequestBuilder(METHOD.DELETE);}public static OtherRequestBuilder patch(){return new OtherRequestBuilder(METHOD.PATCH);}public void execute(final RequestCall requestCall, Callback callback){if (callback == null)callback = Callback.CALLBACK_DEFAULT;final Callback finalCallback = callback;final int id = requestCall.getOkHttpRequest().getId();requestCall.getCall().enqueue(new okhttp3.Callback(){@Overridepublic void onFailure(Call call, final IOException e){sendFailResultCallback(call, e, finalCallback, id);}@Overridepublic void onResponse(final Call call, final Response response){if (call.isCanceled()){sendFailResultCallback(call, new IOException("Canceled!"), finalCallback, id);return;}if (!finalCallback.validateReponse(response, id)){sendFailResultCallback(call, new IOException("request failed , reponse's code is : " + response.code()), finalCallback, id);return;}try{Object o = finalCallback.parseNetworkResponse(response, id);sendSuccessResultCallback(o, finalCallback, id);} catch (Exception e){sendFailResultCallback(call, e, finalCallback, id);}}});}public void sendFailResultCallback(final Call call, final Exception e, final Callback callback, final int id){if (callback == null) return;mPlatform.execute(new Runnable(){@Overridepublic void run(){callback.onError(call, e, id);callback.onAfter(id);}});}public void sendSuccessResultCallback(final Object object, final Callback callback, final int id){if (callback == null) return;mPlatform.execute(new Runnable(){@Overridepublic void run(){callback.onResponse(object, id);callback.onAfter(id);}});}public void cancelTag(Object tag){for (Call call : mOkHttpClient.dispatcher().queuedCalls()){if (tag.equals(call.request().tag())){call.cancel();}}for (Call call : mOkHttpClient.dispatcher().runningCalls()){if (tag.equals(call.request().tag())){call.cancel();}}}public static class METHOD{public static final String HEAD = "HEAD";public static final String DELETE = "DELETE";public static final String PUT = "PUT";public static final String PATCH = "PATCH";}
}

要是没有添加依赖的,去build.gradle添加依赖,没有包的就ALT+ENTER引包。

再说一下这段请求代码,搞过后台的基本都能看懂。

OkHttpUtils.get().url(url).addParams("cuuid","66666").addParams("washDate", dateString).addParams("washTime",timeString).build().execute(new StringCallback() {@Overridepublic void onError(Call call, Exception e, int id) {Log.e("onError:", e.toString());}@Overridepublic void onResponse(String response, int id) {Log.e("onResponse:", response);JSONObject responseJson = (JSONObject) JSONObject.parse(response);String code = responseJson.getString("code");String message = responseJson.getString("message");//保存成功if("100".equals(responseJson.get("code"))){Toast.makeText(getApplicationContext(), code+","+responseJson.get("message"), Toast.LENGTH_LONG).show();}else{Toast.makeText(getApplicationContext(), code+","+responseJson.get("message"), Toast.LENGTH_LONG).show();}}});


发了一个get请求,参数是cuuid,washDate,washTime,这两个时间就是上面从插件

选的。onResponse方法,需要返回标准的json格式,我这里定义的是

{"code":"100","message":"success"},后台需要的接口,这里不写了。

4.最后一步,打包

我这里没有连手机,如果你连手机,打开开发者模式,显示有你的手机,点击ok就好了。


打成apk文件。


第一次打的话,让你写密码什么的,一定要记住。。。

打好了就可以把apk分享给好友下载了。

贴一张我的app的图。





本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/413011.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[css] 相邻兄弟选择器、后代选择器和子选择器三者有什么区别?

[css] 相邻兄弟选择器、后代选择器和子选择器三者有什么区别&#xff1f; 后代选择器与子选择的关系&#xff1a;后代选择器>子选择器。 后代选择器&#xff1a;包括父元素的子元素以及孙子元素&#xff08;代表符号&#xff1a;空格&#xff09;子选择器&#xff1a;包括父…

CompletableFuture的多线程和异步监听实现

大家好,我是烤鸭&#xff1a;今天给大家说的是多线程并发的异步监听的情况。这里不得不说一下CompletableFuture这个类&#xff0c;普通我们执行多线程的时候只需要另外启动一条线程。 说一下线程的3种方式&#xff1a;extends Thread&#xff0c;implements Runnable&#xff…

DCF:A Dataflow-Based Collaborative Filtering Trainging Algorithm

Abstratct:描述了当前协同过滤算法两大技术alternating least square(ALS,最小二乘法)和gradient descent(GD)的确定&#xff1a;原文&#xff1a;Existing collaborative filtering techniques are implemented with either alternating least square algorithm or gradient d…

[css] 举例说明你对相邻兄弟选择器的理解

[css] 举例说明你对相邻兄弟选择器的理解 divp{ //相邻兄弟选择器 background: red; } 符合两个条件就会被选中&#xff1a; 1.紧邻在另一个元素后面 2.两者父元素相同个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢…

HashMap jdk1.7和1.8概述

大家好&#xff0c;我是烤鸭&#xff1a;这是一篇关于HashMap的概述和底层原理的介绍。算是网上很多帖子的综合和我自己的一点想法。HashMap在jdk1.8以前是数组链表。在jdk1.8以后是数组链表红黑树。一点点分析数据结构。1. Map中的entry对象: static class Node<K,V> im…

springboot整合redis修改分区

转载的地址&#xff1a;https://blog.csdn.net/m0_37659871/article/details/81024068#commentBox springboot整合redis修改分区 问题由来 最近使用springboot整合redis&#xff0c;一个系统动态数据源连接不同数据库&#xff0c;缓存使用的redis&#xff0c;那么就需要将不同…

[css] 你是怎么设计css sprites(精灵图)的?有哪些技巧?

[css] 你是怎么设计css sprites&#xff08;精灵图&#xff09;的&#xff1f;有哪些技巧&#xff1f; 首先肯定不会去用PS量&#xff0c;那太费时间了~ 没有webpack以前&#xff0c;用Gulp的gulp.spritesmith插件&#xff0c;这里附上配置源码/* gulpfile.js */ const gulp …

iOS沙盒文件夹及获取路劲方法

iPhone沙盒中有四个文件夹&#xff0c;分别是&#xff1a;documents、tmp、app、library. 1、Documents &#xff1a;用户生成的文档或数据&#xff0c;或者应用不能重新新创建的数据&#xff0c;存储在/Documents目录下&#xff0c;并且会被自动备份到iCloud&#xff1b; 2、A…

springboot多环境加载yml和logback配置

大家好&#xff0c;我是烤鸭&#xff1a;这是一篇关于springboot多环境加载yml和logback配置文件。环境&#xff1a;开发工具 idea(推荐)/eclipse(对yml支持不好)jdk 1.8springboot 1.5.6.RELEASE 1. yml和logback文件1.1 结构,如图所示&#xff1a;1.2 application.yml (默…

[css] 请描述下你对translate()方法的理解

[css] 请描述下你对translate()方法的理解 Single length/percentage value一个长度值或百分比表示X轴和Y轴使用一样的值进行二维上的平移。等同于translate() &#xff08;2D 平移&#xff09;函数指定单个值。Two length/percentage values两个长度值或百分比表示在二维上分…

laydate闪退

1,解决方案一&#xff1a;加 trigger: ‘click’ laydate.render({ elem: this ,format:‘yyyy-MM-dd HH:mm:ss’ ,type:‘datetime’ ,trigger: click’ }); 解决方案二&#xff1a; $("#"dateControlId).removeAttr(“lay-key”);

汇编实验二

》实验结论 1.使用Debug将下面的程序写入内存&#xff0c;逐条执行&#xff08;见1-1&#xff09;&#xff0c;根据指令执行后的实际情况填空&#xff08;见1-2&#xff09; p.s. 已经按实验要求将使用 e 命令将内存单元 0021:0 ~0021:7 连续 8 个字节数据修改为 30H, 31H, 32H…

springboot中的拦截器interceptor和过滤器filter,多次获取request参数

大家好&#xff0c;我是烤鸭&#xff1a; 这是一篇关于springboot的拦截器(interceptor)和过滤器(Filter)。 先说一下过滤器和拦截器。区别&#xff1a;1. servlet请求&#xff0c;顺序&#xff1a;Filter ——> interceptor。2. Filter的作用是对所有进行过滤&#xff…

[css] 怎样去除图片自带的边距?

[css] 怎样去除图片自带的边距&#xff1f; 空隙产生的原因&#xff0c;换行符&#xff0c;空格符&#xff0c;制表符等你空白符&#xff0c;字体不为0的情况下&#xff0c;都会产生一个字符的空隙&#xff0c;空格符好会占据一定宽度&#xff0c;使用inline-block会产生元素间…

Java删除list

方案1>&#xff1a;for循环删除&#xff1a;注意从大到小遍历&#xff0c;不是从小到大&#xff1b; /*** 删除选中项*/private void deleteCheckedItem() {// list&#xff1a;初始化所有的数据&#xff1b;count&#xff1a;最后角标int count list.size() - 1 ;//从大到…

Unable to locate the default servlet for serving static content. Please set the 'defaultServletName'

大家好&#xff0c;我是烤鸭。 今天分享一个莫名其妙的异常及解决方式。 环境&#xff1a; tomcat6 jdk 1.6 异常主体&#xff1a; java.lang.IllegalStateException: Unable to locate the default servlet for serving static content. Please set the defaultServletName p…

iptables原理及规则

iptables简介和原理 我们先来了解以下社么是防火墙 防火墙&#xff1a;隔离功能&#xff0c;工作在网络或主机边缘&#xff0c;对进出网络或主机的数据包基于一定的规则检查&#xff0c;并在匹配某规则时由规则定义的行为进行处理的一组功能的组件&#xff0c;基本上的实现都是…

[css] 让你手写一个reset的文件,你应该怎么写?要考虑哪些方面呢?

[css] 让你手写一个reset的文件&#xff0c;你应该怎么写&#xff1f;要考虑哪些方面呢&#xff1f; 肯定首先考虑的是浏览器本身的样式&#xff0c;还有浏览器兼容。margin&#xff0c;padding >0ul,ol list style:nonea,text-decoration:nonefont-size:100%上标&#xff…

利用cookies跳过登陆验证码

前言在爬取某些网页时&#xff0c;登陆界面时经常遇到的一个坎&#xff0c;而现在大多数的网站在登陆时都会要求用户填写验证码。当然&#xff0c;我们可以设计一套机器学习的算法去破解验证码&#xff0c;然而&#xff0c;验证码的形式多种多样&#xff0c;稍微变一下&#xf…

org.apache.ibatis.reflection.ReflectionException: Error instantiating class with invalid types

大家好&#xff0c;我是烤鸭&#xff0c;记录一个初级异常&#xff0c;百度搜索结果不多&#xff1a; Caused by: org.apache.ibatis.reflection.ReflectionException: Error instantiating class com.xxx.xxx with invalid types 。 java.lang.NoSuchMethodException: com.xx…