记得上篇文章我还在为使用哪种开发语言开发android而发愁,最近使用了一下C#开发android,感觉不是那么爽。查资料也不方便,于是我决定使用java开发,毕竟java我也是学过的,eclipse环境也不陌生。开始吧,天很冷,先上图

这张图我是从真机上截取下来的,这是一个登陆界面。用户输入用户名和密码后,验证,验证通过之后,跳转至另一个Activity。那么我目前采取的方式是Android调用.net WebService的方式。

OK,先看一下Service端。


很熟悉很简单的结构。我们简单看一下Service端的代码

namespace GRLC.WebService{    ///     /// Login 的摘要说明    ///     [WebService(Namespace = "http://tempuri.org/")]    [WebServiceBinding(ConformsTo = WsiProfiles.None)]    [System.ComponentModel.ToolboxItem(false)]    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。    // [System.Web.Script.Services.ScriptService]    public class LoginService : System.Web.Services.WebService    {        [WebMethod]        public LoginResponse CheckLogin(string userNo, string pwd)        {            return LoginBiz.GetInstance().CheckLogin(userNo, pwd);        }    }}

没什么好说的,完了之后我们再看Biz层

public class LoginBiz   {       static LoginBiz loginBiz = new LoginBiz();       private LoginBiz()       { }       public static LoginBiz GetInstance()       {           return loginBiz;       }       public LoginResponse CheckLogin(string name, string pwd)       {           return LoginDAL.GetInstance().CheckLogin(name, pwd);       }   }

也没啥说的,再看Dal层

public class LoginDAL   {       static LoginDAL loginDAL = new LoginDAL();       private LoginDAL()       { }       public static LoginDAL GetInstance()       {           return loginDAL;       }       const string moduleName = "LoginModule";       BonusEntities bonusEntities = new BonusEntities();       private string PwdIsNotCorrect       {           get           {               return this.GetMessageByName("PwdNotCorrect");           }       }       private string UserNotExists       {           get           {               return this.GetMessageByName("UserNotExists");           }       }       private string GetMessageByName(string msgName)       {           return CommonFunction.GetMessageByModuleAndName(moduleName, msgName);       }       public LoginResponse CheckLogin(string name, string pwd)       {           User user = bonusEntities.User.SingleOrDefault(u => u.UseNo == name);           if (user != null)           {               string passWord = Cryptor.Decrypt(user.Pwd);               if (!passWord.Equals(pwd))               {                   return new LoginResponse() { IsSuccess = false, FailMsg = PwdIsNotCorrect };               }               return new LoginResponse() { IsSuccess = true };           }           else           {               return new LoginResponse() { IsSuccess = false, FailMsg = UserNotExists };           }       }   }

在这里我们使用了EntityFrameWork作真正的数据访问层。我一次性把所有表都映射进来了,并设置了他们之间的关联关系。

在这里需要说的是这个GetMessageByModuleAndName方法。

public class CommonFunction    {        private static string BaseDirectory        {            get            {                return AppDomain.CurrentDomain.BaseDirectory;            }        }        private static List GetMessageList()        {            List messageList = new List();            string messageConfigFolder = Path.Combine(BaseDirectory, ConfigHelper.MessageConfigFolder);            if (!Directory.Exists(messageConfigFolder)) return null;            string[] files = Directory.GetFiles(messageConfigFolder, "*.xml", SearchOption.TopDirectoryOnly);            foreach (string file in files)            {                ServiceMessage message = SerializeHelper.XmlDeSerializeByFile(file);                messageList.Add(message);            }            return messageList;        }        public static string GetMessageByModuleAndName(string moduleName, string msgName)        {            string message = string.Empty;            ServiceMessage serviceMsg = new ServiceMessage();            List serviceMessageList = CommonFunction.GetMessageList();            List messageEntityCollection = serviceMessageList.Select(m => m.messageEntityCollection).ToList();            foreach (var msgEntityCollection in messageEntityCollection)            {                MessageEntity messageEntity = msgEntityCollection.SingleOrDefault(msgEntity => msgEntity.Module == moduleName && msgEntity.Name == msgName);                if (messageEntity != null)                {                    message = messageEntity.Content;                    break;                }            }            return message;        }    }

首先这个方法会先从配置文件里面获取到提示信息的配置文件夹,然后遍历xml文件,将所有xml文件中的提示信息通过反序列化放到一个List中,也就是上面的GetMessageList()方法,其实在这里我们可以对代码进行优化,如下

private static List _serviceMessageList;        private static List ServiceMessageList        {            get            {                if (_serviceMessageList == null)                {                    _serviceMessageList = GetMessageList();                    return _serviceMessageList;                }                else                {                    return _serviceMessageList;                }            }        }

那么每次在获取的时候,会先判断_serviceMessageList有没有,如果有,就不再读取文件了。

我们来看一下这个配置文件

<?xml version="1.0" encoding="utf-8"?>    

它对应的实体如下

namespace GRLC.Model.Config{    [XmlRoot("ServiceMessages")]    public class ServiceMessage    {        [XmlElement("Message")]        public MessageEntityCollection messageEntityCollection { get; set; }    }    public class MessageEntityCollection : KeyedCollection    {        protected override string GetKeyForItem(MessageEntity messageEntity)        {            return messageEntity.Name;        }    }    [XmlRoot("Message")]    public class MessageEntity    {        [XmlAttribute("Name")]        public string Name { get; set; }        [XmlAttribute("Module")]        public string Module { get; set; }        [XmlAttribute("Content")]        public string Content { get; set; }    }}

所以在拿到这些msg以后,根据他的module和name就可以拿到对应content。好了上面就是.net的service端。完了之后我们部署一下

部署的时候需要注意如下


接下来我们看一下app端的开发

我们总共有两个Activity,一个是main,一个是index,main界面登成功跳转至index界面。

我们先看一下mai界面的代码

<?xml version="1.0" encoding="utf-8"?>                                                                                            

采用的是线性布局。运行起来就是最开始我贴的那张图。OK,我们先看一下OnCreate


final static String NAMESPACE = "http://tempuri.org/";    final static String METHOD_NAME = "CheckLogin";    final static String SOAP_ACTION = "http://tempuri.org/CheckLogin";    final static String URL = "http://10.0.2.2:2000/LoginService.asmx?wsdl";    EditText txtUserno;    EditText txtPwd;    Button btnLogin;    Button btnCancel;    CheckBox chkDisplay;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        btnLogin = (Button) this.findViewById(R.id.btnLogin);        btnCancel=(Button) this.findViewById(R.id.btnCancel);        txtUserno = (EditText) this.findViewById(R.id.txtUserName);        txtPwd = (EditText) this.findViewById(R.id.txtPwd);        chkDisplay = (CheckBox) this.findViewById(R.id.chkDisplayPwd);        btnLogin.setOnClickListener(new OnClickListener() {            public void onClick(View v) {                String userNo = txtUserno.getText().toString().trim();                String pwd = txtPwd.getText().toString().trim();                Login(userNo, pwd);            }        });        btnCancel.setOnClickListener(new OnClickListener() {            public void onClick(View v) {                txtUserno.setText("");                txtPwd.setText("");            }        });        chkDisplay.setOnCheckedChangeListener(new OnCheckedChangeListener() {            public void onCheckedChanged(CompoundButton cmpButton,                    boolean isChecked) {                if (isChecked) {                    txtPwd                            .setTransformationMethod(HideReturnsTransformationMethod                                    .getInstance());                } else {                    txtPwd.setTransformationMethod(PasswordTransformationMethod                            .getInstance());                }            }        });    }

在页面的最顶端声明了我们需要调用的webservice的信息,注意10.0.2.2是android的内置IP,这个是android访问你本地电脑时使用的IP。如果使用127.0.0.1的话那是在访问你的手机。在Oncreate方法里,我们给按钮注册了事件响应。登录和取消,我们还看到一个checkBox,他的作用是是否让密码明文显示。如果未勾选,如下左所示,否则如右

OK,看完checkBox我们看登录

public void Login(String userNo, String passWord) {        if (!CheckUserInput(userNo, passWord)) {            return;        }        SoapObject response = this.GetServerResponse(userNo, passWord);        boolean isSuccess = Boolean.valueOf(response.getProperty("IsSuccess")                .toString());        if (!isSuccess) {            String failMsg = response.getProperty("FailMsg").toString();            new AlertDialog.Builder(this)                    .setTitle(R.string.WarningMsgTitle)                    .setMessage(failMsg)                    .setIcon(R.drawable.warning)                    .setPositiveButton("确定",null).show();        } else {            Intent intent = new Intent();            Bundle bundle = new Bundle();            bundle.putString("userNo", userNo);            intent.putExtras(bundle);            intent.setClass(main.this, index.class);            startActivityForResult(intent, 0);            finish();        }    }

登录的时候会先checkInput。

private boolean CheckUserInput(String userNo, String passWord) {        if (userNo.equals("")) {            new AlertDialog.Builder(this).setTitle(R.string.WarningMsgTitle)                    .setMessage(R.string.UserNoIsEmpty)                    .setIcon(R.drawable.info)                    .setPositiveButton("确定",                            new DialogInterface.OnClickListener() {                                public void onClick(                                        DialogInterface dialoginterface, int i) {                                    txtUserno.requestFocus();                                }                            }).show();            return false;        }        if (passWord.equals("")) {            new AlertDialog.Builder(this).setTitle(R.string.WarningMsgTitle)                    .setMessage(R.string.UserPWdIsEmpty)                    .setIcon(R.drawable.info)                    .setPositiveButton(                            "确定", new DialogInterface.OnClickListener() {                                public void onClick(                                        DialogInterface dialoginterface, int i) {                                    txtPwd.requestFocus();                                }                            }).show();            return false;        }        return true;    }

checkInput非常简单,如果是空的话弹出提示,如下

OK,如果输入的不是空,那么调用WebService,需要传递两个参数

看一下代码

private SoapObject GetServerResponse(String userNo, String passWord) {        SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);        PropertyInfo pi = new PropertyInfo();        pi.setName("userNo");        pi.setType(String.class);        pi.setValue(userNo);        Request.addProperty(pi);        pi = new PropertyInfo();        pi.setName("pwd");        pi.setType(String.class);        pi.setValue(passWord);        Request.addProperty(pi);        SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(                SoapEnvelope.VER11);        soapEnvelope.dotNet = true;        soapEnvelope.setOutputSoapObject(Request);        HttpTransportSE httpTS = new HttpTransportSE(URL);        try {            httpTS.call(SOAP_ACTION, soapEnvelope);        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (XmlPullParserException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        SoapObject result = null;        try {            result = (SoapObject) soapEnvelope.getResponse();        } catch (SoapFault e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return result;    }

在这里调用WebService并返回SoapObject对象,调用WebService不要忘记引用ksoap

如果没有的话,自己去下载一个。这里调用成功返回以后,如果IsSuccess为true的话,直接跳转至index,并将登陆成功的userNo传给index。如果登陆失败,弹出service端返回的提示信息。但悲剧的是我的真机报错,没有访问到webservice。后来我用手机连接了wlan,Ip地址也改了还是报错

电脑访问无线IP没有问题,如下

但是真机就是连不上,模拟器用10.0.2.2却可以正常访问。

后来查看了一下手机,尝试下面所有的ip都不行。

最后我查了一下电脑ip,使用172.18.73.39,结果调用成功。

调用成功了,哈哈


更多相关文章

  1. 箭头函数的基础使用
  2. NPM 和webpack 的基础使用
  3. Python list sort方法的具体使用
  4. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  5. Android高手进阶教程(二十五)之---Android(安卓)中的AIDL!!!
  6. Android软件安全开发实践
  7. Android中View和ViewGroup介绍
  8. Android(安卓)面试题总结2018(二)
  9. Android(安卓)调用相机拍照,适配到Android(安卓)10?

随机推荐

  1. Android滑动冲突之完美实现RecycleView+
  2. 使用android--建立第一个APP程序
  3. Mac下配置Android NDK环境并搭建Cocos2d-
  4. 在android 下支持ntfs-3g
  5. Android之Android(安卓)apk动态加载机制
  6. Android菜单详解(五)——使用XML生成菜单
  7. 3G Android智能手机视频预览万里
  8. Android中sqlite数据库的简单使用
  9. Android导出一个JAR库/Android如何将程序
  10. android高仿微信视频编辑页-视频多张图片