今天主要学习关于viewgroup的自定义以及复习补充一些相关的知识。
深刻的感觉到项目的重要性,没有实战的经历,对于很多工程性的知识都是表面学习,让人感觉很无力。
想到暑假的一个项目,做一个面试打分系统,我负责安卓端的开发以及安卓端所使用服务器的开发,那会儿还不知道啥叫服务器,就上网搜,学着怎么搭建web service,网上说的感觉很杂, 什么apache、tomcat之类的,我觉得很麻烦,就想要一种最简单的实现方法,然后当时搭建的服务器demo代码如下:
package webserver;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface Web {
@WebMethod
int Login(String user,String pwd);
@WebMethod
String Info(String user);
@WebMethod
String Cla(String user);
@WebMethod
String Res(String user);
@WebMethod
int Give(String giver,String stu,int result,String classid,int gua);
}
如上代码先定义了一个webservice的接口,除了注解之外,跟普通的接口差不多;
之后写了一个接口实现类,代码有点长就在此不贴出了,最后用如下代码进行了webservice的发布:
package webserver;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
public class WebPublish {
public static void main(String[] args)
{
Endpoint.publish("http://localhost:9001/Web_Ser", new Web_T());
System.out.println("成功发布");
}
}
发布之后的效果就是,我的电脑与同局域网下的设备均可以查看到此web service的wsdl文档,我认为此时已经满足了web service的需求了,于是就使用了这种方法;
在后来的学习中,虽然我是做移动端的,但肯定是免不了用到服务器相关的知识,我看到了很多服务器都是使用tomcat发布的,并且在发布之前webservice的时候我也发现了几点,首先在android 使用soap调用的时候,不能通过在url中使用?加入参数的模式获得返回值,并且在浏览器中也不能,其次使用这种方法发布的web service在android端soap调用的时候soap设置doNet()值的使用需要置为false(.NET方式搭建的webservice);如下代码是一个请求web service的android端代码:
package com.example.administrator.gr;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class MainActivity extends AppCompatActivity {
private String result;
private EditText editText;
private EditText editText2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button submit = (Button)findViewById(R.id.button);
Button button = (Button)findViewById(R.id.button75);
editText = (EditText)findViewById(R.id.editText);
editText2 = (EditText)findViewById(R.id.editText2);
submit.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
String user = ((EditText)findViewById(R.id.editText)).getText().toString();
String pwd = ((EditText)findViewById(R.id.editText2)).getText().toString();
if("".equals(user) || "".equals(pwd))
{
Toast.makeText(MainActivity.this,"输入不能为空",Toast.LENGTH_LONG).show();
((EditText)findViewById(R.id.editText)).setText("");
((EditText)findViewById(R.id.editText2)).setText("");
}
else
{
QueryAddressTask queryAddressTask = new QueryAddressTask();
//启动后台任务
queryAddressTask.execute(user,pwd);
}
}
});
button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(MainActivity.this,d.class);
startActivity(intent);
}
});
}
public String getRemoteInfo(String username,String passwd) throws Exception{
String WSDL_URI = "http://192.168.191.1:9001/Web_Ser?wsdl";//wsdl 的uri
String namespace = "http://webserver/";//namespace
String methodName = "Login";//要调用的方法名称
SoapObject request = new SoapObject(namespace, methodName);
// 设置需调用WebService接口需要传入的两个参数mobileCode、userId
request.addProperty("arg0", username);
request.addProperty("arg1", passwd);
//创建SoapSerializationEnvelope 对象,同时指定soap版本号(之前在wsdl中看到的)
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
envelope.bodyOut = request;//由于是发送请求,所以是设置bodyOut
envelope.dotNet = false;//由于是.net开发的webservice,所以这里要设置为true
HttpTransportSE httpTransportSE = new HttpTransportSE(WSDL_URI);
httpTransportSE.call(null, envelope);//调用
// 获取返回的数据
SoapObject object = (SoapObject) envelope.bodyIn;
// 获取返回的结果
try{
result = object.getProperty("return").toString();
}
catch (NumberFormatException e)
{
}
Log.d("debug",result);
return result;
}
class QueryAddressTask extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... params) {
try {
result = getRemoteInfo(params[0],params[1]);
} catch (Exception e) {
e.printStackTrace();
}
//将结果返回给onPostExecute方法
return result+"";
}
protected void onPostExecute(String res)
{
String[] jieguo = res.split(",");
if("1".equals(jieguo[0]))
{
Toast.makeText(MainActivity.this,"欢迎登陆",Toast.LENGTH_LONG).show();
String user = editText.getText().toString();
String pwd = editText2.getText().toString();
Intent intent = new Intent(MainActivity.this,makesureActivity.class);
Bundle bundle = new Bundle();
bundle.putCharSequence("user",jieguo[1]);
intent.putExtras(bundle);
startActivity(intent);
}
else{
Toast.makeText(MainActivity.this,"验证失败",Toast.LENGTH_LONG).show();
}
}
}
}
上述代码中使用了AsyncTask的方式请求网络服务(android中UI线程不能进行耗时操作,需要使用异步操作);今天学习得知这样的搭建方法属于jax-ws(java api for xml web service)的轻量级搭建,传输文本为xml格式。
温故知新,有时候回顾一下之前干过啥还是挺好的,接下来说一下viewgroup的自定义,viewgroup跟view不一样,它是作为一个容器存在的,我们需要处理measure与layout两方面,作为容器就必然会有子视图的存在,我们可以使用getChildAt(int i)方法获取第i个子视图,关于view与measure的方法有很多,其实有时候反而不希望提供那么多已有的方法,学起来,记起来实在麻烦,关于measure的总结可以参考:Measure总结---简书
通过对于下拉刷新实现的学习,具体问题需要具体分析,当需要去解决一个问题的时候,最好的办法是使用已有的方法,找出一种解决途径,其中对于事件的处理还是很巧妙的,关于回调机制我也进行了一些学习:简单来说回调函数就是通过其指针来调用的函数,android是通过java语言实现的,java没有指针,因此在实现回调的时候都是通过接口或者抽象类,回调的过程简单理解为:在A类中定义了一个方法,这个方法中用到一个接口和该接口中的抽象方法,但是抽象方法没有具体实现,需要交给B类去实现,当B类实现该方法后,它本身不会去调用该方法,而是传给A类,供A类去调用,比如事件监听器中就用到了这样的机制。
除此之外,今天第一次访问了《android开发进阶-从小工到专家》的作者的github,其中对于下拉刷新实现已有一篇博客,所以在此就不班门弄斧,直接贴出博客链接:下拉刷新。
最后今天对于开发框架有了第一步的了解,了解还不够深入,希望以后能在实战中用到。