超实用的Android开发自学资料分享全集
Java 学习
我要强调,一定要有Java 基础,而且Java 基础要牢固,当然我也不是说,Java 学的特别好,才能去学习Android,毕竟学习是循序渐进的,所以在以后的学习中要注意,对于Java 系统的学习,我有一下几个推荐;
Introduction to Programming in Java: An Interdisciplinary Approach
http://introcs.cs.princeton.edu/java/home/
普林斯顿的公开课,也有书籍,我觉得可以直接跟着公开课学习就OK 啦;
Java Tutorial - TutorialSpoint
www.tutorialspoint.com/java/
TutorialSpoint 是一个专门技术教程网站,其他教程也可以去看学习;当然你想离线观看,网站还提供了PDF 版
Java Tutorial PDF
www.tutorialspoint.com/java/java_tutorial.pdf
Javanotes 7.0 -- Title Page
http://math.hws.edu/eck/cs124/downloads/javanotes7.pdf
这个是霍巴特威廉史密斯学院的一本书,跟着JDK 版本,已经发行了好多版本;
Android 系列教程
这一段时间,发现了好多学习资源,自己收藏了,不敢独享,所以拿出来和大家分享,如果您发现不错的学习资源,欢迎留言;
而学习的过程中,也忽略了一些问题,比如自己学习的不系统,如果您也是自学的话,一定要注意这个问题,我觉得,除了看官方文档和大牛的博客之外,最重要就找一本好书,把自己的知识系统化;
入门指南
How to get started programming Android apps | HalfApp
http://halfapp.com/blog/get-started-programming-android-apps/
A step by step guide about how to get started and involved in Android Development - Reddit
www.reddit.com/r/Android/comments/1w3woc/a_step_by_step_guide_about_how_to_get_started_and/
Beginning Android Resources · codepath/android_guides Wiki
https://github.com/codepath/android_guides/wiki/Beginning-Android-Resources
我是如何自学Android,资料分享
http://www.jianshu.com/p/2ee0e74abbdf
我推荐的 Android 基础学习路线
http://drakeet.me/android_base_road
Android入门杂谈
http://mmclub.github.io/blog/2014/04/03/start-learning-android/
书籍推荐
首先自己没有很系统地去看一本书,所以我也是搜索,或者实在知乎上别人推荐的,所以,要根据自己的情况,适合自己的书来看;
The Busy Coder's Guide to Android Development
http://commonsware.com/Android/
这是大牛CommonsGuy 开源的一本书,它的更新非常及时,基本上就是跟着SDK 更新的,下载PDF 可以在这里(Four-to-Free Guarantee http://commonsware.com/Android/4-2-free)下载,书籍中源码可以在Github(commonsguy/cw-omnibus https://github.com/commonsguy/cw-omnibus) 中查看;
公开课
How to Develop Android Apps Online Course - Udacity
https://www.udacity.com/course/ud853
Programming Mobile Applications for Android (Coursera)
https://class.coursera.org/android-001/lecture
Android Development For Absolute Beginners - YouTube
https://www.youtube.com/playlist?list=PLB03EA9545DD188C3
系列教程
Home · codepath/android_guides Wiki - codepath
https://github.com/thecodepath/android_guides/wiki
Android 指南,它不仅介绍怎么创建一个最简单的App Demo,循序渐进教你使用各种流行的框架,对于即将工作的同学来说是很用用的;Demo 很有实战意义;
Android tutorial - TutorialSpoint
www.tutorialspoint.com/android/index.htm
是不是特别熟悉呀,对上面提到过,教程特别通俗易懂,代码实例也不错;
Android Development - Vogella
http://www.vogella.com/tutorials/android.html
教程挺通俗易懂
AndroidHive | Tutorials, Games, Apps, Tips |
http://www.androidhive.info/
博主是印度人,博客主要是以教程为主,质量较高,而且会分享比较新的东西;
Android Tutorial | Interactive and Step by step tutorial to learn Android
http://www.codelearn.org/android-tutorial/
Android SDK - Tuts+ Code Category
http://code.tutsplus.com/categories/android-sdk
Android Programming Archives - Learn2Crack
www.learn2crack.com/category/androidprogramming
Android Learning Path | SlideRule
https://www.mysliderule.com/learning-paths/android/learn/
大牛博客推荐
android-cn/android-dev-cn
https://github.com/android-cn/android-dev-cn
主要介绍国内Android 开发大牛;
android-cn/android-dev-com
https://github.com/android-cn/android-dev-com
主要介绍国外Android 开发大牛;
What are must-read Android developer blogs? - Quora
http://www.quora.com/What-are-must-read-Android-developer-blogs
Quora 上的回答
有哪些 Android 大牛的 blog 值得推荐? - 知乎
http://www.zhihu.com/question/19775981
知乎上的回答
开源App
F-Droid | Free and Open Source Android App Repository
https://f-droid.org/
F-Droid 是一个Android 开源App 仓库
Android优秀开源项目 - 小猪爬爬
blog.tisa7.com/android_open_source_projects
The Android Arsenal - A categorized directory of free libraries and tools for Android
https://android-arsenal.com/
在这里,找到最新最流行的Android 开源类库
Trinea/android-open-project - Trinea
https://github.com/Trinea/android-open-project
大牛Trinea 写的Android 开源项目汇总
开发工具
Great Code Examples & Snippets | Codota
http://www.codota.com/
一个Android 代码搜索引擎;前两天发现了这个工具就爱不释手,写了篇文章——《Android 开发工具之Codota——搜索最好的Android 代码 - 简书》,让你参考入门。
Gradle
www.gradleware.com
知乎上我回答的《如何从eclipse转入android studio,感觉Gradle什么的很难理解的。有什么教程吗? - Tikitoo 的回答 - 知乎》,可以参考。
Android Studio
http://www.jianshu.com/p/874ff12a4c01
从Google 的态度就可以看出,Android Studio 就是未来,而且在最近发布了正式版,教程在网上也不少。
Android User Interface | User Experience | Inspiration source for Android Designers and Developers
http://androiduiux.com/
Android App Patterns
www.android-app-patterns.com
Iconfinder - 400,000+ free and premium icons
https://www.iconfinder.com/
一个Icon 搜索引擎
google/material-design-icons - github
https://github.com/google/material-design-icons
Google 把官方的Material Design 1000+ 的Icon 开源了,不仅仅只有Android 版,而且还有Web 和iOS,真是业界良心呀。
inferjay/AndroidDevTools
https://github.com/inferjay/AndroidDevTools
inferjay 总结的开发工具,并且提供了国内的镜像。
Genymotion - A faster Android emulator
https://www.genymotion.com/
Genymotion 是Android 的虚拟机,比官方的快了不知多少啊,它是基于Virtual Box,并且提供了插件。
订阅
Android 周刊 http://androidweekly.net/
Android开发技术周报 http://www.androidweekly.cn/
码农周刊 - Android https://github.com/nemoTyrant/manong#ANDROID
资源
Best resources for Android development
http://www.androidauthority.com/best-resources-android-development-372414/
Resources every Android developer must know
http://www.bongizmo.com/blog/android-resources-each-developer-should-know/
中文版——《Android开发者必知的开发资源 - ImportNew
》,译者是ImportNew - 黄小非 http://www.importnew.com/3988.html
参考
http://www.quora.com/What-are-the-best-resources-to-learn-Android-development
http://www.quora.com/What-are-the-best-websites-to-learn-Android-development-tools#
http://www.sitepoint.com/12-android-tutorials-beginners/
http://nimooli.com/blog/best-android-books-2014/
举个例子:比如要在一个LinearLayout中添加一个Button, 子view是Button,父view是LinearLayout。 子view的属性就是通过LayoutParams来设置的,注意是LinearLayout.LayoutParams,因为子view的高度,宽度这些都是针对父view的,要告诉父view自己要占用多大空间,所以是LinearLayout(原来总是会用子view的LayoutParams来设置,错误)
public class MyActivity extends Activity { private Context mContext; private LinearLayout mLinearLayout; private LinearLayout.LayoutParams mLayoutParams; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mContext = this; mLinearLayout = (LinearLayout)findViewById(R.id.parent_view); mLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); Button button = new Button(mContext); button.setText("添加button"); mLinearLayout.addView(button, mLayoutParams); } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:id="@+id/parent_view" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
Android 利用addView 动态给Activity添加View组件
本文主要讲述如何动态给UI界面添加布局和控件,在编程的时候很多时候需要动态显示一些内容,在动态添加View的时候,主要使用addView方法。
1. addView方法简介
在Android 中,可以利用排版View的 addView 函数,将动态产生的View 物件加入到排版View 中。
例子如下:
Activity代码:
public class helloWorld extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView( R.layout.main ); // 取得LinearLayout 物件 LinearLayout ll = (LinearLayout)findViewById(R.id.viewObj); // 将TextView 加入到LinearLayout 中 TextView tv = new TextView(this); tv.setText(Hello World); ll. addView ( tv ); // 将Button 1 加入到LinearLayout 中 Button b1 = new Button(this); b1.setText(取消); ll. addView ( b1 ); // 将Button 2 加入到LinearLayout 中 Button b2 = new Button(this); b2.setText(确定); ll. addView ( b2 ); // 从LinearLayout 中移除Button 1 ll. removeView ( b1 ); } }
上述代码的位置,是垂直顺序排列的因为界面代码Linerlayout的orientation设置的是vertical的,但是为了美观,需要设置添加的View的位置和样式。在添加View的时候分为两类来介绍,一种是布局(例如:Linearlayout等),一种是控件(例如:Button,TextView等等。)
2. 动态添加布局(包括样式和位置)
下面的例子将介绍如何动态添加布局,基本内容和上面的代码一致,主要注重如何控制添加的布局的位置。在控制布局的位置的时候使用LayoutParam类来实现。
例子:
界面代码和上面的界面代码类似,就不在重复介绍。
Activity类部分代码:
RelativeLayout rl = new RelativeLayout(this); //设置RelativeLayout布局的宽高 RelativeLayout.LayoutParams relLayoutParams=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); this.addView(rl, relLayoutParams);
3. 动态添加控件
动态添加控件和添加布局很相似,下述代码主要注重看控制控件的位置,下面的代码和第二项添加布局的补充,在新添加的布局里面再添加控件。
界面代码同样不在重复。
Activity类部分代码:
RelativeLayout rl = new RelativeLayout(this); //设置RelativeLayout布局的宽高 RelativeLayout.LayoutParams relLayoutParams=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); TextView temp = new TextView(this); temp .setId(1); temp.setText(“图片”); rl.addView(temp); TextView tv = new TextView(this); tv.setText(“文字”); tv.setId(2); LayoutParams param1 = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); param1.addRule(RelativeLayout.BELOW, 1);//此控件在id为1的控件的下边 rl.addView(tv,param1); Button update = new Button(this); update.setText(Button); LayoutParams param2 = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); param2.addRule(RelativeLayout.RIGHT_OF, 1);//此控件在id为1的控件的右边 rl.addView(update,param2); this.addView(rl, relLayoutParams);
注意:控制位置和样式的时候,布局和控件使用的方法是一样的。
Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务。
Activity中所有操作都与用户密切相关,是一个负责与用户交互的组件,可以通过setContentView(View)来显示指定控件。
在一个android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent进行通信。
Activity生命周期
安卓活动由一个返回栈管理
安卓活动有四个状态
1.运行状态
当一个活动位于栈顶的时候,这个活动就处于运行状态,也就是和用户进行交互的那个界面。
2.暂停状态
当活动不处于栈顶,但依然可见。意思就是这个活动没有被完全覆盖,上面有一层对话框之类的。
3.停止状态
活动不处于栈顶,完全不可见。这个好理解吧,就是用户看不到了。
4.销毁状态
活动从栈中移除了,也就是被用户关闭了。
Activity共有七个回调方法,覆盖了活动整个生命周期
1.onCreate()
活动创建时调用,一般被用来初始化。
2.onStart()
由不可见重新可见的时候调用。
3.onResume()
当活动到达栈顶的时候调用,也就是活动准备和用户交互的时候调用
4.onPause()
启动或者恢复另一个活动的时候调用。
5.onStop()
当活动完全不可见的时候会执行,注意是完全不可见,若是是启动一个对话框形式的活动,则不会启动。
6.onDestroy()
当活动被销毁之前调用
7.onRestart()
当活动由停止状态变为运行状态之前调用
下图很直观的表示了活动的生命周期
你可以用如下示例代码 仔细探索一下 通过logcat打印的内容 你能很容易的弄明白
public class MainActivity extends Activity { public static final String TAG="MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG,"onCreate"); Log.d(TAG,this.toString()); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); if(savedInstanceState!=null) { String temp=savedInstanceState.getString("data_key"); Log.d(TAG,temp); } Button startNormal=(Button)findViewById(R.id.start_normal_activity); Button startDialog=(Button)findViewById(R.id.start_dialog_activity); startNormal.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(MainActivity.this,NormalActivity.class); startActivity(intent); } }); startDialog.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(MainActivity.this,DialogActivity.class); startActivity(intent); } }); } @Override public void onStart(){ super.onStart(); Log.d(TAG,"onStart"); } @Override public void onResume(){ super.onResume(); Log.d(TAG,"onResume"); } @Override public void onPause(){ super.onPause(); Log.d(TAG,"onPause"); } @Override public void onStop(){ super.onStop(); Log.d(TAG,"onStop"); } @Override public void onDestroy(){ super.onDestroy(); Log.d(TAG,"onDestroy"); } @Override public void onRestart(){ super.onRestart(); Log.d(TAG,"onRestart"); }
关于启动模式
activity的启动也共有四种
要修改activity的启动模式,需要在AndroidManifest.xml中修改activity标签下的 android:launchMode
<activity android:name=".MainActivity" android:launchMode="singleTop" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
1.standard
这是活动的默认启动模式 ,这种启动模式,每次启动都会在栈中新建一个该活动的实例
好比在FirstActivity的基础上再启动一个FirstActivity 如果你要返回的话你就要按两次返回键才能返回到桌面
2.singleTop
这种模式很好的解决了上一种模式的问题
如果FirstActivity这个活动已经在栈顶了 那么如果你要再启动FirstActivity 是不会再创建新的实例了的
但是这种方法仅限于FirstActivity在栈顶的情况,如果FirstActivity不在栈顶,也就是不在用户能看到的界面,那么还是会创建新的实例。
3.singleTask
singleTask完美解决创建重复活动实例的情况。每次启动活动,它会自动查找栈中是否存在该活动的实例,若存在直接使用,不存在才创建
4.singleInstance
这个比较特殊,它启动活动时,会新建一个栈来存放新启动的活动。这种模式可以解决不同应用程序之间调用活动的问题。
来先看下效果,有个感性的认识。
中间那个提示其实是一个activity,好的,下面开始一步步实现这个神奇的效果。
第一步:设计对话框页面activity_simulate_dialog.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center_horizontal" android:background="#ffffff" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:orientation="vertical" > <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="提示" /> <TextView android:id="@+id/tv_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="确认购买该场次电影票吗?" /> <LinearLayout android:layout_width="200dp" android:layout_height="80dp" android:gravity="center" android:orientation="horizontal" > <Button android:id="@+id/btn_cancel" android:layout_width="100dp" android:layout_height="40dp" android:text="取消" /> <Button android:id="@+id/btn_confirm" android:layout_width="100dp" android:layout_height="40dp" android:text="确认" /> </LinearLayout> </LinearLayout> </RelativeLayout>
第二步:编写弹出窗Activity SimulateDialogActivity.java
ackage com.figo.study; import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class SimulateDialogActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_simulate_dialog); Button btn_cancel = (Button) findViewById(R.id.btn_cancel); btn_cancel.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { finish(); } }); Button btn_confirm = (Button) findViewById(R.id.btn_confirm); btn_confirm.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { finish(); } }); } //点击外部区域关闭该activity @Override public boolean onTouchEvent(MotionEvent event) { finish(); return true; } }
第三步:style.xml设计style
<item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> <item name="android:windowAnimationStyle">@style/Anim_scale</item> </style> <style name="Anim_scale" parent="@android:style/Animation.Activity"> <item name="android:activityOpenEnterAnimation">@anim/scale_in</item> <item name="android:activityOpenExitAnimation">@anim/scale_out</item> <item name="android:activityCloseEnterAnimation">@anim/scale_in</item> <item name="android:activityCloseExitAnimation">@anim/scale_out</item>
第四步:anim文件夹设计动画
页面进入动画scale_in.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <scale android:fromXScale="1.0" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:toXScale="1.0" android:fromYScale="0.0" android:toYScale="1.0" android:duration="200" android:pivotX="0" android:pivotY="10%" /> </set>
面退出动画scale_out.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <scale android:fromXScale="1.0" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:toXScale="1.0" android:fromYScale="1.0" android:toYScale="0.0" android:duration="200" android:pivotX="0" android:pivotY="10%" /> </set>
第五步:关键一步,在AndroidManifest.xml注册模拟对话框Activity
<activity android:name="com.figo.study.SimulateDialogActivity" android:label="@string/app_name" android:theme="@style/SimulateDialog" > </activity>
第六步:调用对话框Activity
Button btnDialog = (Button) findViewById(R.id.btn_dialog); btnDialog.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(TestActivity.this, SimulateDialogActivity.class); startActivity(intent); } });
将Android Activity设置成对话框式
将activity设置成对话框样式,只需在activity属性里面增加下面一句代码:
android:theme="@android:style/Theme.Dialog"
然后可以activity左边增加一个小图片,让它更像Dialog,代码如下:
package com.home.testactivitydialog; import android.os.Bundle; import android.view.Window; import android.app.Activity; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_LEFT_ICON); setTitle("测试对话框式activity");// 设置标题 setContentView(R.layout.main);// 设置布局内容 // 设置左边图标 getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, android.R.drawable.ic_dialog_alert); } }
但是上面的设置往往还不能满足实际需求,因为样子、背景和一些属性使用的默认的,下面使用style自定义一个,以后可以根据实际需要自行更改:
<style name="dialog" parent="@android:style/Theme.Dialog"> <!-- 去黑边 --> <item name="android:windowFrame">@null</item> <!-- 设置是否可滑动 --> <item name="android:windowIsFloating">true</item> <!-- 设置是否透明 --> <item name="android:windowIsTranslucent">true</item> <!-- 无标题 --> <item name="android:windowNoTitle">true</item> <!-- 背景 --> <item name="android:background">@null</item> <!-- 窗口背景 --> <item name="android:windowBackground">@android:color/transparent</item> <!-- 是否变暗 --> <item name="android:backgroundDimEnabled">false</item> <!-- 点击空白部分activity不消失 --> <item name="android:windowCloseOnTouchOutside">false</item> </style>
这样在主题里直接引用:
android:theme="@style/dialog"
点击activity空白处不消失也可以代码里面设置,在onCreate()方法里面加上:
setFinishOnTouchOutside(false);
Android客户端利用Socket连接服务器的大概思路如下:
客户端首次连接服务器:
socket = new Socket(); SocketAddress address = new InetSocketAddress(svrHost, svrPort); socket.connect(address, TIME_OUT); socket.setSoTimeout(TIME_OUT); in = new BufferedReader(new InputStreamReader( socket.getInputStream())); out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())), true);
连接服务器之后,调用注册或者登录,获取连接的token。 以后每次的连接获取信息都要带上约定的token。
连接建立以后,socket不必关闭,毕竟每次connect也浪费资源,可以一直挂住等待服务端的推送或者心跳等消息。
while (!exitSocket) { try { if (!socket.isClosed() && socket.isConnected() && !socket.isInputShutdown()) { char[] lenBuffer = new char[13]; int len = 0; try { len = in.read(lenBuffer); } catch (Exception e) { Utils.debug("SocketSvr socket read timeout"); stopSocketByException(true); }
每次的请求,server端返回的数据都包含在lenBuffer中,一般是约定好的json或者是其他格式的信息。
整体思路是和TCP是一样的,更多的问题出现在细节处理上和socket的生命周期的维护上。
比如如果断网或者出现异常导致socket出现exception,这时可能需要把当前的socket关闭(timeoutException应该不需要重启),然后重新启动新的socket,但是对于终端用户来说,应当避免的是让用户感觉到有界面的异动,需要立即重新连接server。
Android客户端通过socket与服务器通信实例
由于Android里面可以完全使用java.io.*包和java.net.*包,那么,实际上,逻辑部分与J2SE没有区别。只是UI代码不一样。
Android客户端通过socket与服务器通信分为下面5步:
(1)通过IP地址和端口实例化Socket,请求连接服务器;
socket = new Socket("10.14.114.127",54321); //IP:10.14.114.127,端口54321
(2)获取Socket流以进行读写,并把流包装进BufferWriter或者PrintWriter
PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
这里涉及了三个类:socket.getOutputStream得到socket的输出字节流,OutputStreamWriter是字节流向字符流转换的桥梁,BufferWriter是字符流,然后再包装进PrintWriter。
(3)对Socket进行读写
out.println(message);
(4)关闭打开的流
out.close();
完整工程代码如下:
package com.yarin.android.Examples_08_04; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class Activity01 extends Activity { private final String DEBUG_TAG = "Activity01"; private TextView mTextView = null; private EditText mEditText = null; private Button mButton = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mButton = (Button)findViewById(R.id.Button01); mTextView = (TextView)findViewById(R.id.TextView01); mEditText = (EditText)findViewById(R.id.EditText01); //登陆 mButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { Socket socket = null; String message = mEditText.getText().toString() + "/r/n"; try { //创建Socket // socket = new Socket("192.168.1.110",54321); socket = new Socket("10.14.114.127",54321); //IP:10.14.114.127,端口54321 //向服务器发送消息 PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true); out.println(message); //接收来自服务器的消息 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String msg = br.readLine(); if ( msg != null ) { mTextView.setText(msg); } else { mTextView.setText("数据错误!"); } //关闭流 out.close(); br.close(); //关闭Socket socket.close(); } catch (Exception e) { // TODO: handle exception Log.e(DEBUG_TAG, e.toString()); } } }); } }
布局文件main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/TextView01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="这里显示接收到服务器发来的信息" /> <EditText android:id="@+id/EditText01" android:text="输入要发送的内容" android:layout_width="fill_parent" android:layout_height="wrap_content"> </EditText> <Button android:id="@+id/Button01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="发送" /> </LinearLayout>
AndroidManifest.xml文件如下
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yarin.android.Examples_08_04" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".Activity01" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-sdk android:minSdkVersion="5" /> </manifest>
当然,还有服务器端得代码
package com.yarin.android.Examples_08_04; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class Server implements Runnable { public void run() { try { //创建ServerSocket ServerSocket serverSocket = new ServerSocket(54321); while (true) { //接受客户端请求 Socket client = serverSocket.accept(); System.out.println("accept"); try { //接收客户端消息 BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); String str = in.readLine(); System.out.println("read:" + str); //向服务器发送消息 PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(client.getOutputStream())),true); out.println("server message"); //关闭流 out.close(); in.close(); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } finally { //关闭 client.close(); System.out.println("close"); } } } catch (Exception e) { System.out.println(e.getMessage()); } } //main函数,开启服务器 public static void main(String a[]) { Thread desktopServerThread = new Thread(new Server()); desktopServerThread.start(); } }
先开启服务器代码,
java Server即可
然后启动android模拟器。运行结果
这是Android客户端。输入12345,点击发送:
这是服务器端收到的消息
相关文章
- 今天小编在这里就来给Photoshop的这一款软件的使用者们来说下火龙变冰龙的制作教程,各位想知道具体的制作步骤的使用者们,那么下面就快来跟着小编一起看看制作教程吧。...2016-09-14
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
Illustrator渐变网格工具绘制可爱的卡通小猪教程分享
今天小编在这里就来给Illustrator的这一款软件的使用者们来说一说渐变网格工具绘制可爱的卡通小猪的教程,各位想知道具体制作方法的使用者们,那么下面就快来跟着小编一...2016-09-14Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 不知不觉功夫熊猫这部电影已经出到3了,今天小编在这里要教大家的是用Photoshop制作功夫熊猫3的海报,各位想知道制作方法的,那么下面就来跟着小编一起看看吧。 给各...2016-09-14
- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 今天小编在这里就来给photoshop的这一款软件的使用者们来说一说日系小清新通透人像的调色教程,各位想知道具体的调色步骤的使用者们,那么下面就快来跟着小编一起看一看...2016-09-14
- 如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
- 深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
- 下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
- java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
- TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
- 什么是js跨域呐?js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。要...2015-10-30
android.os.BinderProxy cannot be cast to com解决办法
本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20- 下面来给大家分享两个关于php威盾解密的例子,一个是批量解密一个是超级算法的解密都非常的好,大家有举的进入参考。 例子,批量解密 代码如下 复制代码 ...2016-11-25
- mysqli封装了诸如事务等一些高级操作,同时封装了DB操作过程中的很多可用的方法。应用比较多的地方是 mysqli的事务。...2013-10-02
- 这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
- 什么是js跨域呐?js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。要...2015-10-30