截至昨天,完成了对于安卓课程设计的汇报,觉得对于自己写的项目作出记录还是挺好的一个习惯。
首先给出一个演示:
整个项目的框架:
服务器: NodeJs
使用的是Express 的框架,但是在很多的企业开发当中更喜欢koa这个东西,之后应该要去学一学。
数据库: Mysql
在项目当中使用的建表语句比较简单,主要就是为了可以存储数据,不得不说的是利用NodeJs 的Mysql 操控方法真的很方便,对于我这种需求简单的小白来说非常友善。
在做项目的过程中对于自己需要的功能做出了封装,具体的代码放在文章的后面吧。
移动端: Android
利用AndroidStudio完成了Android端的开发,总的感受来说就是Android的布局要是可以和HTML那样支持的布局方式更丰富一点就好了。
比如在HTML语言当中,做出一个矩形圆角只要直接border-radius参数调整就可以了,但是在Android当中需要自己写一个Shape然后在background当中配置,
这个过程就比较繁琐,但是知道之后也就是多敲几个代码的事情。
具体实现:
新闻类 App 那么新闻数据一定是必不可少的,但是自己整理新闻材料这个比较耗时,于是找到了网上提供的API,免费,数据封装的到位,使用体验极佳。
API平台叫聚合数据。
用户的注册登录,做这个板块的时候,一个碰到的问题是,不知道如何在Android中选择图片,上传图片,在服务器中也不知道如何处理传输的文件。
最后还是在网上找到了解决办法,具体的内容放在了上一个博客当中,这里就不再写了。
对于每一个新闻做了一个评论区,用户可以在评论区内评论,当然对于这个发出的评论,服务器端会检测发出的内容是否符合规范,有无脏话之类。
这个检测的功能是基于百度的AI文本识别做的,不得不说百度AI真的强。
用户不满意的评论也可以通过左滑评论删除,在这里对用户删除的是否是自己的评论做出了判断,如果不是自己的评论那肯定是不能让他删啊,这里的代码学了很久。
对于每一个新闻可以实现用户的收藏和删除实现方式和评论也差不多。
最后是代码的总结环节:
数据库封装代码:
1 var mysql = require('mysql'); 2 var connection = mysql.createConnection({ 3 host : 'localhost', 4 user : 'root', 5 password : '******', 6 database : 'dailynews' 7 }); 8 connection.connect(); 9 /** 10 异步回调请求 11 封装插入语句 12 params: 13 表名 14 插入数据的 JSON 对象 15 resolve 回调事件 16 reject 回调事件 17 **/ 18 19 /** 20 调用测试 21 params = { 22 'nickname' : 'loenvom', 23 'eid' : '919087313', 24 'pass' : 'zzzzzz' 25 } 26 27 insertdata('User', params, (rows)=>{ 28 console.log(rows) 29 }, (err)=>{ 30 console.log(err) 31 }) 32 **/ 33 34 35 36 /** 37 * 38 * 调用测试 39 * selectdata('User', ' where nickname = "zzz" ', (rows)=>{ 40 console.log(rows.length) 41 }, (err)=>{ 42 console.log(err); 43 }) 44 */ 45 46 module.exports = { 47 selectdata : function selectdata(table_name, limitation, resolve, reject) 48 { 49 let sql = 'select * from ' + table_name + ' ' + limitation 50 51 connection.query(sql, (err, rows) => { 52 if(err) reject(err) 53 else resolve(rows) 54 }) 55 }, 56 insertdata: function insertdata(table_name, params, resolve, reject) 57 { 58 var sql = "insert into " + table_name + " (" 59 let first = 0 60 for(key in params) 61 { 62 if(first == 0) 63 { 64 sql = sql + key 65 first = 1 66 }else{ 67 sql = sql + ',' + key 68 } 69 } 70 sql = sql + ') values (' 71 first = 0 72 for(key in params) 73 { 74 if(first == 0) 75 { 76 sql = sql + '"' + params[key] + '"' 77 first = 1 78 }else{ 79 sql = sql + ', "' + params[key] + '"' 80 } 81 } 82 sql = sql + ')' 83 console.log(sql) 84 connection.query(sql, (err, rows) => { 85 if(err) reject(err) 86 else resolve(rows) 87 }) 88 }, 89 updatedata : function updatedata(table_name, limitation, params, resolve, reject){ 90 sql = 'update ' + table_name + ' set ' + params[0] + ' = ' + params[1] + limitation 91 connection.query(sql, (err, rows)=>{ 92 if(err) reject(err) 93 else resolve(rows) 94 }) 95 }, 96 deleltedata : function deleltedata(table_name, limitation, resolve, reject) 97 { 98 sql = 'delete from ' + table_name + limitation 99 100 console.log(sql) 101 connection.query(sql, (err, rows)=>{ 102 if(err) reject 103 else resolve(rows) 104 }) 105 } 106 }
对于自定义的RecyclerView的左滑事件
private fun setupItemTouchHelper(context: Context){ val helper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback( ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT){ override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { return true } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { //在这个过程当中获取当前的元素
//根据ID给出处理 var tmp = CommentList[viewHolder.adapterPosition] if(tmp.userid != userid) { Toast.makeText(context, "您不能删除不属于您的评论", Toast.LENGTH_LONG).show() recyclerview_comment.adapter?.notifyDataSetChanged() return } val url = DataUtil.REMOVECOMMENT+ "?uniquekey=" + tmp.uniquekey + "&userid=" + tmp.userid + "&words=" + tmp.words + "&time=" + tmp.time Log.d("debug", url) Thread{ try { val client = OkHttpClient() val request = Request.Builder() .url(url) .build() val response = client.newCall(request).execute() val responseData = response.body()?.string() if(responseData!=null) { if(responseData == "true") { runOnUiThread { Toast.makeText(context, "已为您删去该条评论", Toast.LENGTH_LONG).show() } }else if(responseData == "false") { runOnUiThread { Toast.makeText(context, "删除失败", Toast.LENGTH_LONG).show() } } }else { Log.d("debug", "responsedata is null") } }catch (e : java.lang.Exception) { e.printStackTrace() } CommentList.removeAt(viewHolder.adapterPosition) runOnUiThread { recyclerview_comment.adapter?.notifyItemRemoved(viewHolder.adapterPosition) } }.start() } })
helper.attachToRecyclerView(recyclerview_comment)
}
对于百度AI的使用
这里由于是第一次,尴尬的遇到了看完官方文档也没明白怎么安装的问题,一开始下载了开发包,但是其实直接命令行下载就可以了
至于调用部分就很简单了
app.get('/send', (req, res)=>{ let userid = req['query']['userid'] let words = req['query']['words'] let uniquekey = req['query']['uniquekey'] let time = req['query']['time'] params = { 'userid' : userid, 'words' : words, 'uniquekey' : uniquekey, 'time' : time } client.textCensorUserDefined(words).then(function(data) { /* {"conclusion":"不合规","log_id":16096720353914868,"data":[{"msg":"存在低俗辱骂不合规","conclusion":"不合规", "hits":[{"probability":0.76831967, "datasetName":"百度默认文本反作弊库","words":[]}],"subType":5,"conclusionType":2,"type":12}],"conclusionType":2} */ console.log(data) if(data['conclusion'] == '合规') { db.insertdata('comment', params, result=>{ res.end('polite') }, error=>{ }) }else{ res.end("impolite"); } }, function(e) { console.log(e) }); })