登录模块

  •  数据库设计

   

如图所示创建了如上的数据库由于没有注册功能人为添加了两个用户:

数据库创建语句:

public static final String CREATE_task ="create table user ("+ "id integer primary key autoincrement, "+"remenberPassword text,"+"autoLogin text,"+ "username text, "+ "password text"+ ")";public static final String CREATE_task2 ="create table Travel ("+ "id integer primary key autoincrement, "+ "travelName text, "+ "content text,"+ "traveldate date,"+ "userID integer"+ ")";
@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_task);db.execSQL(CREATE_task2);}

与数据库对应创建了两个对应于两张表的数据库操作DBBean:代码如下:

  1. Travel表的TravelDBean

 插入语句:

public long insert(TravelBean travel) {ContentValues newValues =new ContentValues();newValues.put("content", travel.getContent());newValues.put("traveldate",travel.getTraveldate());newValues.put("travelName",travel.getTravelName());  newValues.put("userID",travel.getUserID());   return db.insert(DB_Table, null, newValues);    }

根据用户名加载全部行程的语句,此处加载按时间排序进行加载:

 public TravelBean[] LoadAllData(String Uername) {Cursor result =db.query( DB_Table, new String[] {"id","travelName","content","traveldate","userID"}, “userID”+” = ”+Uername , null, null, null,"traveldate desc");return ConvertToTravelBean(result);}

根据返回的游标,将数据封装进对象语句:

private  TravelBean[] ConvertToTravelBean(Cursor result) {// TODO Auto-generated method stubint resultCounts=result.getCount();if(resultCounts==0||!result.moveToFirst()) {return null;}TravelBean[] travel=new TravelBean[resultCounts];        for(int i=0;i<resultCounts;i++) {travel[i]=new TravelBean();travel[i].setContent(result.getString(result.getColumnIndex("content")));travel[i].setTravelName(result.getString(result.getColumnIndex("travelName")));travel[i].setTraveldate(result.getString(result.getColumnIndex("traveldate")));travel[i].setUserID(result.getString(result.getColumnIndex("userID")));   travel[i].setID(result.getString(result.getColumnIndex("id")));   System.out.println(travel[i].getTravelName());result.moveToNext();  }return travel;}

根据travel的ID号修改旅行名称、内容、时间语句:

public void updateOneData(String travelName,String content,String traveldate,String id) {ContentValues updateValues=new ContentValues();updateValues.put("content", content);updateValues.put("travelName", travelName);updateValues.put("traveldate", traveldate);db.update(DB_Table, updateValues, "id"+" = " +id, null);}

根据旅行的ID号删除一条旅行记录:

public long deleteOneData(String id) {return db.delete(DB_Table, "id"+" ="+id, null);}

Uer对应的UserDBBean

    创建数据库,并返回一个SQLIteDatabse对象供给TravelDBean使用:

public SQLiteDatabase open() throws SQLiteException{dbOpenhelper=new MyDatabaseHelper(context, DB_NAME, null, DB_VERSION);try {db=dbOpenhelper.getWritableDatabase();return db;}catch(SQLiteException e) {db=dbOpenhelper.getReadableDatabase();return db;}}

插入用户对象,注册功能为实现,但需要插入两个用户进行测试:

public long insert(UserBean user) {ContentValues newValues =new ContentValues();newValues.put("remenberPassword", user.getRemenberPassword());newValues.put("password",user.getPassword());newValues.put("username",user.getUsername());  newValues.put("autoLogin",user.getAutoLogin());return db.insert(DB_Table, null, newValues);   }

根据用户名加载用户:

public UserBean queryByUsername(String username) {UserBean userBean=null;Cursor result =db.query( DB_Table, new String[] {"username","password","remenberPassword","autoLogin"},  "username"+" = '"+username+"'", null, null, null,null);if(result.getCount()!=0) {result.moveToFirst();userBean=new UserBean();userBean.setPassword(result.getString(1));userBean.setAutoLogin(result.getString(3));userBean.setRemenberPassword(result.getString(2));userBean.setUsername(username);       }return userBean;}

 根据用户名来更新记住密码、自动登陆的状态

public void updateOneData(String username,String remenberPassword,String autoLogin ) {if(username!=null) {ContentValues updateValues=new ContentValues();updateValues.put("autoLogin", autoLogin);updateValues.put("remenberPassword", remenberPassword);db.update(DB_Table, updateValues, "username"+" = " +username, null);}else {return;}        }

两个用来封装数据的实体Bean,代码如下:

UserBean:

public class UserBean {private String id="";private String username="";private String password="";private String remenberPassword="";private String autoLogin="";public String getRemenberPassword() {return remenberPassword;}public void setRemenberPassword(String remenberPassword) {this.remenberPassword = remenberPassword;}public String getAutoLogin() {return autoLogin;}public void setAutoLogin(String autoLogin) {this.autoLogin = autoLogin;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}

TravelBean:

public class TravelBean {private String ID="";private String travelName="";private String content="";private String traveldate="";private String userID="";public String getID() {return ID;}public void setID(String iD) {ID = iD;}public String getTravelName() {return travelName;}public void setTravelName(String travelName) {this.travelName = travelName;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getTraveldate() {return traveldate;}public void setTraveldate(String traveldate) {this.traveldate = traveldate;}public String getUserID() {return userID;}public void setUserID(String userID) {this.userID = userID;}}
  • 登录界面设计                                    

 登录界面 源代码

<TextViewandroid:layout_width="match_parent"android:layout_height="50dp"android:text="登录界面"android:gravity="center"android:textSize="30sp"/><View android:layout_width="match_parent" android:layout_height="1dp"android:background="@color/orange_main"/>
<RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:layout_marginLeft="32dp"android:layout_marginRight="32dp"android:layout_marginTop="120dp"><ImageViewandroid:id="@+id/img_account"android:layout_width="19dp"android:layout_height="20dp"android:layout_alignParentBottom="true"android:layout_marginBottom="4dp"android:layout_marginLeft="4dp"android:scaleType="fitXY"android:src="@drawable/icon_login_account"/><EditTextandroid:id="@+id/et_account"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_gravity="center"android:layout_marginBottom="4dp"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/img_account"android:background="@null"android:hint="@string/account"android:maxLines="1"android:textColor="@android:color/black"android:textColorHint="@color/tv_gray_deep"android:textSize="14dp"/><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:layout_alignParentBottom="true"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/img_account"android:background="@color/orange_light"/></RelativeLayout><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:layout_marginLeft="32dp"android:layout_marginRight="32dp"><ImageViewandroid:id="@+id/img_pw"android:layout_width="18dp"android:layout_height="20dp"android:layout_alignParentBottom="true"android:layout_marginBottom="4dp"android:layout_marginLeft="4dp"android:scaleType="fitXY"android:src="@drawable/icon_login_pw"/><EditTextandroid:id="@+id/et_password"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_gravity="center"android:layout_marginBottom="4dp"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/img_pw"android:background="@null"android:hint="@string/password"android:inputType="textPassword"android:maxLines="1"android:textColor="@android:color/black"android:textColorHint="@color/tv_gray_deep"android:textSize="14dp"/><ImageViewandroid:id="@+id/iv_see_password"android:layout_width="20dp"android:layout_height="20dp"android:src="@drawable/image_password_bg"android:layout_centerVertical="true"android:layout_alignParentRight="true"android:scaleType="fitXY"/><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:layout_alignParentBottom="true"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/img_pw"android:background="@color/orange_light"/></RelativeLayout>
<CheckBoxandroid:id="@+id/checkBox_password"android:padding="10dp"android:textSize="14dp"android:layout_gravity="center"android:layout_width="wrap_content"android:layout_weight="1"android:layout_height="wrap_content"android:text="@string/check_password"android:textColor="@color/top_bar_normal_bg" android:checked="false"/><CheckBoxandroid:id="@+id/checkBox_login"android:padding="10dp"android:textSize="14dp"android:layout_gravity="center"android:layout_width="wrap_content"android:layout_weight="1"android:layout_height="wrap_content"android:text="@string/check_login"android:textColor="@color/top_bar_normal_bg" android:checked="false"/>

​​​​​​登录界面功能

           登录界面可隐藏显示密码:

实现代码:首先构建一个选择器,选择器代码如下:

<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/icon_see_pass" android:state_selected="false"/><item android:drawable="@drawable/icon_nosee_pass" android:state_selected="true"/></selector>

然后在Login.xml文件中调用该选择器:

<ImageViewandroid:id="@+id/iv_see_password"android:layout_width="20dp"android:layout_height="20dp"android:src="@drawable/image_password_bg"android:layout_centerVertical="true"android:layout_alignParentRight="true"android:scaleType="fitXY" />    

最后通过设置该选择器控件的点击事件,来达到显示密码,与不显示密码,此时要更换图片的状态,以及设置密码框的 setInputType类型,来使密码可见。具体代码如下:

 if (iv_see_password.isSelected()) {iv_see_password.setSelected(false);//密码不可见et_password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);} else {iv_see_password.setSelected(true);//密码可见et_password.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);}

登录界面可记住密码、自动登陆:

由以上两张图片登录成功后注销登陆回来仍然显示当前密码:

由两张图片用户选择自动登陆,登录之后,退出APP,在进去自动登陆。若注销,则自动登陆状态自动取消,方便用户更换账号。

输入密码错悟提示如上图所示:

实现代码思想如下:

我点击登陆后,会向数据库更新用户的记下密码、自动登陆的状态,并且将当前用户的账号用SharedPreferences类更新在xml配置文件(保存上一次登陆的账号)中,用户登陆之前从数据库中根据根xml配置文件中保存的用户账号把用户所有信息加载出来,并封装在User对象中,我根据此User的记下密码、自动登陆的状态,做出相应的处理;首先将账号加载到用户控件,然后若记下密码我就将密码显示到密码控件上,若是自动登陆,那么直接进行Login()登陆方法。具体代码如下:

 查找上一次加载的用户,并从数据库中将此用户所有信息获取。

 SharedPreferencesUtils helper = new SharedPreferencesUtils(this, "setting");String lastLoginUserName = helper.getString("name");System.out.println("lastLoginUserName"+lastLoginUserName);user= userBean.queryByUsername(lastLoginUserName);

验证该用户记住密码、自动登陆的状态:

//判断是否记住密码if (remenberPassword()) {checkBox_password.setChecked(true);//勾选记住密码setTextNameAndPassword();//把密码和账号输入到输入框中} else {setTextName();//把用户账号放到输入账号的输入框中}//判断是否自动登录if (autoLogin()) {checkBox_login.setChecked(true);login();//去登录就可以}

判断记住密码方法代码如下:

private boolean remenberPassword() {if(user.getRemenberPassword().equals("ture"))return true;elsereturn false;}

将密码以及账号更新UI界面,代码如下:

 public void setTextNameAndPassword() {UserBean user1=userBean.queryByUsername(user.getUsername());if(user1!=null) {et_name.setText("" +user1.getUsername());et_password.setText("" + user1.getPassword());}}

只用账户更新UI界面,代码如下:

public void setTextName() {UserBean user1=userBean.queryByUsername(user.getUsername());if(user1!=null) {et_name.setText("" + user1.getUsername());}}

判断用户的自动登陆状态,代码如下:

private boolean autoLogin() {//获取SharedPreferences对象,使用自定义类的方法来获取对象if(user!=null) {if(user.getAutoLogin().equals("true")) {return true;}}return false;}

       重写记住密码、与自动登陆的状态改变监听函数:做到,如选择自动登陆,那么记住密码应自动被勾选,如果取消记住密码,那么自动登陆也将自动取消。重写OnCheckedChangeListener函数:具体代码如下:

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {if (buttonView == checkBox_password) {  //记住密码选框发生改变时if (!isChecked) {   //如果取消“记住密码”,那么同样取消自动登陆checkBox_login.setChecked(false);}} else if (buttonView == checkBox_login) {   //自动登陆选框发生改变时if (isChecked) {   //如果选择“自动登录”,那么同样选中“记住密码”checkBox_password.setChecked(true);}}}

登录成功获取失败的消息提示,代码如下:

 public void showToast(final String msg) {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(LoginActivity.this, msg, Toast.LENGTH_SHORT).show();}});}

自动登录部分,先验证账号密码是不是为空,在进行登陆。若为空消息提示登陆失败。

若不为空且校验成功,则将进行页面跳转,并将用户名带过去。此处因为不涉及更新UI但是要访问数据库,就创建了一个子线程处理登录模块。具体代码如下:

private void login() {//先做一些基本的判断,比如输入的用户命为空,密码为空,若是直接返回提示错误if (et_name.getText().toString().trim().isEmpty()){showToast("你输入的账号为空!");return;}if (et_password.getText().toString().trim().isEmpty()){showToast("你输入的密码为空!");return;}Thread loginRunnable = new Thread() {@Overridepublic void run() {super.run();mLoginBtn.setClickable(false);//点击登录后,设置登录按钮不可点击状态//睡眠2秒try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}user= userBean.queryByUsername(et_name.getText().toString().trim());//判断账号和密码if (et_name.getText().toString().trim().equals(user.getUsername()) &&et_password.getText().toString().trim().equals(user.getPassword())) {showToast("登录成功");loadCheckBoxState();//记录下当前用户记住密码和自动登录的状态;SharedPreferencesUtils helper = new SharedPreferencesUtils(LoginActivity.this, "setting");helper.putValues(new SharedPreferencesUtils.ContentValue("name", et_name.getText().toString().trim()));//将上一次登陆人的账号存入xml文件Intent intent=new Intent(LoginActivity.this, LoginAfterActivity.class);intent.putExtra("username", et_name.getText().toString().trim());startActivity(intent);finish();//关闭页面} else {System.out.println("username"+user.getUsername());System.out.println("password"+user.getPassword());showToast("输入的登录账号或密码不正确");}mLoginBtn.setClickable(true); //这里解放登录按钮,设置为可以点击}};loginRunnable.start();}

​​​​​​​行程界面模块

  • 行程界面就一个自定义标题组件,与一个ListView组件,具体代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><includelayout="@layout/title_travel"android:layout_width="match_parent"android:layout_height="wrap_content" ></include><ListViewandroid:id="@+id/listView1"android:layout_width="match_parent"android:layout_height="wrap_content" android:divider="#dd430b"></ListView></LinearLayout>

自定义组件代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal" ><TextViewandroid:id="@+id/textView1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="行程安排" android:textColor="@color/black_translucent"android:textSize="30dp"     android:gravity="center"android:textAlignment="center"/></LinearLayout>
  • 行程界面功能实现:截图

登录之后,按下”注销“返回登陆界面。

添加完条记录,点击添加出来一跳添加框,填好信息点击”保存“如下图按时间最大往低排序显示,如下图所示:

选中最后一条信息进行删除,之后,如上图显示:下面进行修改操作:将”baixue“的行程内容更改为”chifan“:

从上图看到数据库中数据已经改变。

  1. 注销功能代码如下:
backLogin.setOnClickListener(new OnClickListener() { @Overridepublic void onClick(View v) {//更新用户自动登录的状态人为设为falseuserBean.updateOneData(username, "ture", "false");//创建记住密码和自动登录是默认不选,密码为空startActivity(new Intent(LoginAfterActivity.this, LoginActivity.class));}});

   2. 增加行程的功能代码主要是增加一行TableRow组件,里面内嵌三个EditText组件和一个保存按钮组件,保存按钮实现,点击保存那么,将数据插入到数据库,将此组件从TableRowLsit链表中删除,从数据库重新加载全部数据更新UI界面:

addTravel.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {clear();TableRow tableRow=new TableRow(LoginAfterActivity.this);tableRow.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));final MyEditText et1=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));final MyEditText et2=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));final MyEditText et3=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));tableRow.addView(et1);tableRow.addView(et2);tableRow.addView(et3);final TravelBean travel=new TravelBean();Button save=new Button(LoginAfterActivity.this);save.setText("保存");tableRow.addView(save);tableRowList.add(2,tableRow);save.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {travel.setUserID(username);travel.setTravelName(et1.getText().toString());travel.setContent(et2.getText().toString());travel.setTraveldate(et3.getText().toString());System.out.println("我被触发了");travelDB.insert(travel);tableRowList.remove(2);queryAll();          }});/*updateButtonList.add(update);*/queryAll();    }});queryAll();System.out.println("列表长度为:"+tableRowList.size());}

​​​​​​​3. 加载所有数据更新UI界面,若有数据那么将数据加载到界面,并且动态创建删除、修改按钮,并注册监听事件;删除按钮:从数据库中删除该条记录,并回调”加载全部函数“更新界面。修改按钮:根据记录ID号,对该行程记录进行更新。具体代码如下

 public void queryAll() {/*lv.removeAllViews();*/if(!firstLogin)clear();//清除ListView原来的组件firstLogin=false;final TravelBean[] sf= travelDB.LoadAllData(username);/*TextView tvNew=new TextView(this);*//*tvNew.setText("没有数据");*/if(sf!=null) {for( int i=0;i<sf.length;i++) {System.out.println("共有:"+i);/*"ID:"+sf[i].getId()+*/TableRow tr=new TableRow(this);final MyEditText et1=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));et1.setText(" "+sf[i].getTravelName());final MyEditText et2=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));et2.setText(sf[i].getContent());final MyEditText et3=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));et3.setText(sf[i].getTraveldate());Button update=new Button(this);update.setText("修改");final TravelBean sfman=sf[i];final String id=sf[i].getID();update.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {travelDB.updateOneData(et1.getText().toString(),et2.getText().toString(),et3.getText().toString(),id);      }});/*updateButtonList.add(update);*/Button delete=new Button(this);delete.setText("删除");delete.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubtravelDB.deleteOneData(sfman.getID());queryAll();}});tr.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));tr.addView(et1);tr.addView(et2);tr.addView(et3);tr.addView(update);tr.addView(delete);tableRowList.add(tr);}}mAdapter.setTableRowList1(tableRowList);//清空ListView链表/*mAdapter.setTableRowList(tableRowList);*/lv.setAdapter(mAdapter);}

​​​​​​​4. 根据屏幕大小调整动态创建的组件的宽度,具体代码如下:

  获取当前屏幕宽度:

   WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics dm = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(dm);ScreenWidth =  dm.widthPixels;  // 屏幕宽度(dp)ScreenHeight = dm.heightPixels;// 屏幕高度(dp)

 对创建的组件宽度进行设置:

text1.setWidth((int)(0.25*ScreenWidth));
Text2.setWidth((int)(0.25*ScreenWidth));
Text3.setWidth((int)(0.25*ScreenWidth));
Text4.setWidth((int)(0.25*ScreenWidth));
final MyEditText et1=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));
final MyEditText et2=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));
final MyEditText et3=new MyEditText(LoginAfterActivity.this,(int)(0.25*ScreenWidth));

清除TableRowList中的除注销登陆、增加行程、和标题栏之外的所有TableRow组件。

public void clear() {if(tableRowList.size()!=0&&tableRowList!=null) {for(int i=0;i<tableRowList.size();i++) {if(tableRowList.get(i).getChildCount()==5) {tableRowList.remove(i);i--;}}}}

Android 行程APP简单介绍相关推荐

  1. android 网络篇简单介绍

    1 简介 本文简单介绍android 开发中常用的webview .url. volley. json解析等网络工具.由于篇幅问题,这里只做简单介绍并不做详解. 2 WebView的用法 2.1 简单 ...

  2. Android IBinder机制简单介绍

    原理简介 我们都知道android 是通过IBinder来实现IPC(Inter Process Communication)进程间通信的... 参考:Android进程间通信(IPC)机制Binde ...

  3. Android逆向工具简单介绍

    目录 一.Android逆向概述 1.什么是Android逆向 2.逆向过程 3.逆向用途 1)APP自动化执行程序脚本 2)修改APP的功能 3)APP安全 二.常用逆向工具介绍 1.APP抓包工具 ...

  4. Android事件分发简单介绍

    简单的讨论下关于Android的事件分发,其实网上的介绍很多,但是每次看完我都记的很晕,而我也只想知道当不同的返回值事件走的流程,所以这也只为自己做个简单的记录 首先说一下关于事件分发ViewGrou ...

  5. 2种Android图表的简单介绍+折线图、饼图的例子,字节跳动移动架构师学习笔记

    setTitle("PieChartActivity"); pie = (PieChart) findViewById(R.id.pie); //②输入数据 //其中两个数字对应的 ...

  6. android ibinder 机制,Android IBinder机制简单介绍

    原理简介 我们都知道android 是通过IBinder来实现IPC(Inter Process Communication)进程间通信的... 借用一下: 1. Client.Server和Serv ...

  7. android之PackageManager简单介绍

    PackageManager相关 本类API是对全部基于载入信息的数据结构的封装,包含下面功能: 安装,卸载应用查询permission相关信息 查询Application相关信息(applicati ...

  8. Android开发_Animation简单介绍

    Android的2种Animation模式: 1. Tween Animation:通过对场景里的对象不断做图像变换(平移.缩放.旋转)产生动画效果,即是一种渐变动画: 2. Frame Animat ...

  9. GCM Google官方示例的简单介绍和使用

    GCM Google官方示例的简单介绍和使用 准备工作 翻墙 先翻墙,翻不了墙一切都白搭-- Google账号 申请Google账号 进入Google开发管理台 创建工程(Google管理台上的Pro ...

最新文章

  1. sysdba登录不需要密码验证?
  2. c语言行计数程序,C语言非常简单的字符统计程序50行
  3. mqtt消息推送 java_MQTT+ActiveMQ实现消息推送(服务器端java实现)
  4. Android开发之shape自定义ProgressBar进度条样式
  5. OpenCV2:应用篇 三维重建
  6. Ubuntu 20.10 代号 Groovy Gorilla,第二个以猿类命名版本,将于 10 月 22 日发布
  7. 两个简单的前台显示构架01
  8. 协议实现objective C 协议的实现
  9. Python的序列Ⅰ
  10. Java web--过滤器
  11. 算法设计与分析——排序算法:十大排序算法总结
  12. 几家大的券商的PB系统以及算法交易概况大致是怎样的?
  13. Windows Server 2008 R2 远程管理
  14. 英国脱欧对GDPR的实施有影响吗?
  15. 你觉得最好用的地图导航软件是哪一个?这3款App供你选择
  16. 用两个小样例来解释单例模式中的“双重锁定”
  17. SAP PLM CVAPI_DOC_VIEW 获取DMS文档原件URL地址示例(Originals File)
  18. 利用echarts做图表统计
  19. Mysql组复制(MGR)——操作
  20. 【STM32F429开发板用户手册】第33章 STM32F429的SPI总线应用之驱动DAC8563(双通道,16bit分辨率,正负10V)

热门文章

  1. python 多次读取文件的细节
  2. 关于a标签不能调用js方法的小细节,你注意到了么?
  3. 配置快捷键让Total Commander跳转到某个目录
  4. Windows Phone 资源管理与换肤思考
  5. vbs调用WebService -- 使用xmlhttp
  6. this和arguments
  7. HTTP和HTTPS详解
  8. 躺平,躺下就能赢吗?
  9. Linux块设备IO子系统
  10. 【Pytorch神经网络实战案例】13 构建变分自编码神经网络模型生成Fashon-MNST模拟数据