超实用的Android开发自学资料分享全集

 更新时间:2016年9月20日 19:55  点击:1584
本文是自学Android开发整理的非常有用的自觉资料,绝对的干货,打算零基础自学Android开发的同学值得参考,如果有java基础的话,就更方便了。

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/

Android应用中动态添加view是非常普遍的效果,本文我们学习一下在开发中如何动态添加view的两个实例,学习子view的属性怎么设置。

举个例子:比如要在一个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是Android组件中最基本也是最为常见用的四大组件之一,本文我们来讲讲activity 生命周期以及启动模式。

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

  这个比较特殊,它启动活动时,会新建一个栈来存放新启动的活动。这种模式可以解决不同应用程序之间调用活动的问题。

对话框在手机app中应用非常广,本文我们主要通过Activity实现弹出模拟对话框的步骤,这样模拟的好处是可以自定义样式,UI友好。

来先看下效果,有个感性的认识。

01.png


中间那个提示其实是一个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应用连接服务器的方式有很多,常用的是TCP和通过Socket方式,这两种方式各有利弊,本文我们主要讲讲利用Socket的方式连接服务器的原理。

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,点击发送:

TCP_CLIENT


这是服务器端收到的消息


tcp_server

[!--infotagslink--]

相关文章

  • Photoshop火龙变冰龙制作教程分享

    今天小编在这里就来给Photoshop的这一款软件的使用者们来说下火龙变冰龙的制作教程,各位想知道具体的制作步骤的使用者们,那么下面就快来跟着小编一起看看制作教程吧。...2016-09-14
  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • Illustrator渐变网格工具绘制可爱的卡通小猪教程分享

    今天小编在这里就来给Illustrator的这一款软件的使用者们来说一说渐变网格工具绘制可爱的卡通小猪的教程,各位想知道具体制作方法的使用者们,那么下面就快来跟着小编一...2016-09-14
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • Photoshop功夫熊猫电影海报制作步骤分享

    不知不觉功夫熊猫这部电影已经出到3了,今天小编在这里要教大家的是用Photoshop制作功夫熊猫3的海报,各位想知道制作方法的,那么下面就来跟着小编一起看看吧。 给各...2016-09-14
  • Android模拟器上模拟来电和短信配置

    如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
  • 夜神android模拟器设置代理的方法

    夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
  • android自定义动态设置Button样式【很常用】

    为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
  • photoshop日系小清新通透人像调色教程分享

    今天小编在这里就来给photoshop的这一款软件的使用者们来说一说日系小清新通透人像的调色教程,各位想知道具体的调色步骤的使用者们,那么下面就快来跟着小编一起看一看...2016-09-14
  • Android WebView加载html5页面实例教程

    如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
  • 深入理解Android中View和ViewGroup

    深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
  • Android自定义WebView网络视频播放控件例子

    下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
  • Android用MemoryFile文件类读写进行性能优化

    java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
  • Android设置TextView竖着显示实例

    TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
  • js实现跨域的4种实用方法原理分析

    什么是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威盾解密的例子分享

    下面来给大家分享两个关于php威盾解密的例子,一个是批量解密一个是超级算法的解密都非常的好,大家有举的进入参考。 例子,批量解密 代码如下 复制代码 ...2016-11-25
  • PHP mysql与mysqli事务使用说明 分享

    mysqli封装了诸如事务等一些高级操作,同时封装了DB操作过程中的很多可用的方法。应用比较多的地方是 mysqli的事务。...2013-10-02
  • Android 实现钉钉自动打卡功能

    这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
  • js实现跨域的4种实用方法原理分析

    什么是js跨域呐?js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。要...2015-10-30