1.AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.glsite.qqloginweb"> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:networkSecurityConfig="@xml/network_security_config"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>2.QQLoginWeb\app\src\main\res\xml\network_security_config.xml
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config>3.activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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=".MainActivity"> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="60dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@mipmap/ic_launcher" /> <Button android:id="@+id/bt_login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="36dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:text="登录" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/cb_remember" /> <EditText android:id="@+id/et_number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="32dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:ems="10" android:hint="请输入您的账号" android:inputType="textPersonName" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.503" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/iv" /> <EditText android:id="@+id/et_password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:ems="10" android:hint="请输入您的密码" android:inputType="textPassword" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/et_number" /> <CheckBox android:id="@+id/cb_remember" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="52dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:text="记住用户名和密码" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/et_password" /> </android.support.constraint.ConstraintLayout>4.MainActivity.java
package com.glsite.qqloginweb; import android.content.SharedPreferences; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.Toast; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static final int STATUS_SUCCESS = 1; private static final int STATUS_ERROR = 2; private EditText mEtNumber; private EditText mEtPassword; private CheckBox mCbRemember; private Button mBtLogin; private SharedPreferences mSp; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case STATUS_SUCCESS: Toast.makeText(MainActivity.this, (String)msg.obj, Toast.LENGTH_SHORT).show(); break; case STATUS_ERROR: Toast.makeText(MainActivity.this,"登录失败,服务器或网络出错", Toast.LENGTH_SHORT).show(); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSp = this.getSharedPreferences("config", this.MODE_PRIVATE); mEtNumber = findViewById(R.id.et_number); mEtPassword = findViewById(R.id.et_password); mCbRemember = findViewById(R.id.cb_remember); mBtLogin = findViewById(R.id.bt_login); mBtLogin.setOnClickListener(this); restoreInfo(); } /** * 从sp文件当中读取信息 */ private void restoreInfo() { String number = mSp.getString("number", ""); String password = mSp.getString("password", ""); mEtNumber.setText(number); mEtPassword.setText(password); } /** * 登录按钮的点击事件 * @param v */ @Override public void onClick(View v) { final String number = mEtNumber.getText().toString().trim(); final String password = mEtPassword.getText().toString().trim(); if (TextUtils.isEmpty(number) || TextUtils.isEmpty(password)) { Toast.makeText(this,"用户名和密码不能为空", Toast.LENGTH_SHORT).show(); return; } else { // 判断是否需要记录用户名和密码 if (mCbRemember.isChecked()) { // 被选中状态,需要记录用户名和密码 // 需要将数据保存到sp文件当中 SharedPreferences.Editor editor = mSp.edit(); editor.putString("number", number); editor.putString("password", password); editor.commit();// 提交数据,类似关闭流,事务 } new Thread(){ @Override public void run() { try { String urlPath = "http://192.168.1.130:8080/Day10/LoginServlet?username=" + number + "&password=" + password; URL url = new URL(urlPath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); int code = conn.getResponseCode(); if (code == 200) { InputStream is = conn.getInputStream(); String result = StreamUtils.readStream(is); Message msg = Message.obtain(); msg.what = STATUS_SUCCESS; msg.obj = result; mHandler.sendMessage(msg); } else { Message msg = Message.obtain(); msg.what = STATUS_ERROR; mHandler.sendMessage(msg); } } catch (Exception e) { e.printStackTrace(); Message msg = Message.obtain(); msg.what = STATUS_ERROR; mHandler.sendMessage(msg); } } }.start(); } } }5.StreamUtils.java
package com.glsite.qqloginweb; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import java.io.ByteArrayOutputStream; import java.io.InputStream; /** * @author glsite.com * @version $Rev$ * @des ${TODO} * @updateAuthor $Author$ * @updateDes ${TODO} */ public class StreamUtils { public static String readStream(InputStream is){ try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while(( len = is.read(buffer))!=-1){ baos.write(buffer, 0, len); } is.close(); String result = baos.toString(); if(result.contains("gb2312")){ return baos.toString("gb2312"); }else{ return result; } } catch (Exception e) { e.printStackTrace(); return null; } } public static Bitmap readBitmap(InputStream is){ return BitmapFactory.decodeStream(is); } }
测试:
package com.glsite.qqloginweb; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; /** * Instrumented test, which will execute on an Android device. * * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { @Test public void useAppContext() { // Context of the app under test. Context appContext = InstrumentationRegistry.getTargetContext(); assertEquals("com.glsite.qqloginweb", appContext.getPackageName()); } } package com.glsite.qqloginweb; import org.junit.Test; import static org.junit.Assert.*; /** * Example local unit test, which will execute on the development machine (host). * * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> */ public class ExampleUnitTest { @Test public void addition_isCorrect() { assertEquals(4, 2 + 2); } }================================================================================
2.post请求实现登入
用runOnUiThread,不用 Handler
MainActivity.java
package com.glsite.qqloginweb; import android.content.SharedPreferences; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.Toast; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static final int STATUS_SUCCESS = 1; private static final int STATUS_ERROR = 2; private EditText mEtNumber; private EditText mEtPassword; private CheckBox mCbRemember; private Button mBtLogin; private SharedPreferences mSp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSp = this.getSharedPreferences("config", this.MODE_PRIVATE); mEtNumber = findViewById(R.id.et_number); mEtPassword = findViewById(R.id.et_password); mCbRemember = findViewById(R.id.cb_remember); mBtLogin = findViewById(R.id.bt_login); mBtLogin.setOnClickListener(this); restoreInfo(); } /** * 从sp文件当中读取信息 */ private void restoreInfo() { String number = mSp.getString("number", ""); String password = mSp.getString("password", ""); mEtNumber.setText(number); mEtPassword.setText(password); } /** * 登录按钮的点击事件 * @param v */ @Override public void onClick(View v) { final String number = mEtNumber.getText().toString().trim(); final String password = mEtPassword.getText().toString().trim(); if (TextUtils.isEmpty(number) || TextUtils.isEmpty(password)) { Toast.makeText(this,"用户名和密码不能为空", Toast.LENGTH_SHORT).show(); return; } else { // 判断是否需要记录用户名和密码 if (mCbRemember.isChecked()) { // 被选中状态,需要记录用户名和密码 // 需要将数据保存到sp文件当中 SharedPreferences.Editor editor = mSp.edit(); editor.putString("number", number); editor.putString("password", password); editor.commit();// 提交数据,类似关闭流,事务 } new Thread(){ @Override public void run() { try { String urlPath = "http://192.168.1.130:8080/Day10/LoginServlet"; URL url = new URL(urlPath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(5000); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");// 设置发送的数据为表单类型,会被添加到http body当中 String data = "username=" + URLEncoder.encode(number, "utf-8") + "&password=" + URLEncoder.encode(password, "utf-8"); conn.setRequestProperty("Content-Length", String.valueOf(data.length())); // post的请求是把数据以流的方式写了服务器 // 指定请求输出模式 conn.setDoOutput(true); conn.getOutputStream().write(data.getBytes()); int code = conn.getResponseCode(); if (code == 200) { InputStream is = conn.getInputStream(); String result = StreamUtils.readStream(is); showToastInAnyThread(result); } else { showToastInAnyThread("请求失败"); } } catch (Exception e) { e.printStackTrace(); showToastInAnyThread("请求失败"); } } }.start(); } } /** * 在任意现成当中都可以调用弹出吐司的方法 * @param result */ private void showToastInAnyThread(final String result) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show(); } }); } }StreamUtils.java
package com.glsite.qqloginweb; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import java.io.ByteArrayOutputStream; import java.io.InputStream; /** * @author glsite.com * @version $Rev$ * @des ${TODO} * @updateAuthor $Author$ * @updateDes ${TODO} */ public class StreamUtils { public static String readStream(InputStream is){ try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while(( len = is.read(buffer))!=-1){ baos.write(buffer, 0, len); } is.close(); String result = baos.toString(); if(result.contains("gb2312")){ return baos.toString("gb2312"); }else{ return result; } } catch (Exception e) { e.printStackTrace(); return null; } } public static Bitmap readBitmap(InputStream is){ return BitmapFactory.decodeStream(is); } }