Android:未建立连接时应用程序崩溃

时间:2014-05-01 06:05:36

标签: android http-post

我正在尝试创建一个需要连接到本地服务器以提取数据的应用程序! 当有连接时,应用程序工作正常!但是当连接断开时,应用程序会等待大约15秒然后崩溃!我在互联网上看到了所有可能的解决方案但没有人为我工作! 请一手解决这个问题 这是源代码!

package com.example.chap6_5;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.channels.UnresolvedAddressException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    EditText Username, Password;
    TextView Error_Login;
    Button Button_Login;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Username = (EditText) findViewById(R.id.username);
        Password = (EditText) findViewById(R.id.password);
        Error_Login = (TextView)findViewById(R.id.ErrorLogin);
        Button_Login = (Button)findViewById(R.id.login);

        Button_Login.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                new DownloadTextTask().execute("http://192.168.1.100/PHP_MVC/mobile/MLogin.php");

            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    // ---Connects using HTTP POST---
    public InputStream OpenHttpPOSTConnection(String url) {
        InputStream inputStream = null;
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);


            // ---the key/value pairs to post to the server---
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("username", Username.getText().toString()
                    .toString()));
            nameValuePairs.add(new BasicNameValuePair("password", Password.getText().toString()));
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse httpResponse = httpclient.execute(httpPost);
            inputStream = httpResponse.getEntity().getContent();
        }
         catch (ConnectTimeoutException  e)
         {
             Log.d("OpenHttpPOSTConnection TIMEOUT", e.getLocalizedMessage());
         }
        catch (Exception e) {
            Log.d("OpenHttpPOSTConnection", e.getLocalizedMessage());
        }
        return inputStream;
    }

    private String DownloadText(String URL) {
        int BUFFER_SIZE = 2000;
        InputStream in = null;
        try {
            in = OpenHttpPOSTConnection(URL);

        } 

        catch (Exception e) {
            Log.d("Networking", e.getLocalizedMessage());
            return "";
        }
        InputStreamReader isr = new InputStreamReader(in);
        int charRead;
        String str = "";
        char[] inputBuffer = new char[BUFFER_SIZE];
        try {
            while ((charRead = isr.read(inputBuffer)) > 0) {
                // ---convert the chars to a String---
                String readString = String
                        .copyValueOf(inputBuffer, 0, charRead);
                str += readString;
                inputBuffer = new char[BUFFER_SIZE];
            }
            in.close();
        } catch (IOException e) {
            Log.d("DownloadText", e.getLocalizedMessage());
            return "";
        }
        return str;
    }

    private class DownloadTextTask extends AsyncTask<String, Void, String> {
        protected String doInBackground(String... urls) {
            return DownloadText(urls[0]);
        }

        @Override
        protected void onPostExecute(String result) {
            try {

                JSONObject jsonObject = new JSONObject(result);
                String success = jsonObject.getString("Success");
                Toast.makeText(getBaseContext(), success, Toast.LENGTH_LONG).show();
                if (Integer.parseInt(success)==1)
                {
                    Log.d("DownloadTextTask", "success");
                    Intent i_Dashboard = new Intent(getApplicationContext(),Dashboard.class);
                    startActivity(i_Dashboard);
                    finish();
                }
                else
                {
                    Error_Login.setText("Error Login : Username/password are wrong !");
                }
                Log.d("DownloadTextTask", result);

            } catch (Exception e) {
                Log.d("DownloadText", e.getLocalizedMessage());
            }

        }
    }
}

[EDITED]新的OnCreate方法

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Username = (EditText) findViewById(R.id.username);
        Password = (EditText) findViewById(R.id.password);
        Error_Login = (TextView)findViewById(R.id.ErrorLogin);
        Button_Login = (Button)findViewById(R.id.login);

        Button_Login.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                ConnectionDetector conn = new ConnectionDetector(getApplicationContext());
                 if(conn.isConnectingToInternet())
                 {
                     Toast.makeText(getApplicationContext(), "CONNECTEDs", Toast.LENGTH_LONG).show();
                new DownloadTextTask().execute("http://192.168.1.100/PHP_MVC/mobile/MLogin.php");
                 }
                 else
                     Toast.makeText(getApplicationContext(), "No connection", Toast.LENGTH_LONG).show();

            }
        });

    }

这是logcat:

05-01 06:08:07.673: D/OpenGLRenderer(1276): TextureCache::get: create texture(0xb881bb38): name, size, mSize = 13, 7488, 1106852
05-01 06:08:10.773: D/OpenHttpPOSTConnection TIMEOUT(1276): Connect to /192.168.1.100:80 timed out
05-01 06:08:10.773: W/dalvikvm(1276): threadid=10: thread exiting with uncaught exception (group=0xa62b0288)
05-01 06:08:10.773: E/AndroidRuntime(1276): FATAL EXCEPTION: AsyncTask #1
05-01 06:08:10.773: E/AndroidRuntime(1276): java.lang.RuntimeException: An error occured while executing doInBackground()
05-01 06:08:10.773: E/AndroidRuntime(1276):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.lang.Thread.run(Thread.java:856)
05-01 06:08:10.773: E/AndroidRuntime(1276): Caused by: java.lang.NullPointerException
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.io.Reader.<init>(Reader.java:64)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.io.InputStreamReader.<init>(InputStreamReader.java:122)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.io.InputStreamReader.<init>(InputStreamReader.java:59)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at com.example.chap6_5.MainActivity.DownloadText(MainActivity.java:118)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at com.example.chap6_5.MainActivity.access$0(MainActivity.java:106)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at com.example.chap6_5.MainActivity$DownloadTextTask.doInBackground(MainActivity.java:140)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at com.example.chap6_5.MainActivity$DownloadTextTask.doInBackground(MainActivity.java:1)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
05-01 06:08:10.773: E/AndroidRuntime(1276):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
05-01 06:08:10.773: E/AndroidRuntime(1276):     ... 5 more
05-01 06:08:10.893: D/OpenGLRenderer(1276): TextureCache::get: create texture(0xb87ab998): name, size, mSize = 24, 7488, 1114340
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::flush: target size: 668604
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 2, 5184, 1109156
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 4, 20736, 1088420
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 10, 2304, 1086116
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 13, 7488, 1078628
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 6, 7488, 1071140
05-01 06:08:11.329: D/OpenGLRenderer(1276): TextureCache::callback: name, removed size, mSize = 1, 1048576, 22564

非常感谢!

3 个答案:

答案 0 :(得分:2)

第一种方法

OpenHttpPOSTConnection功能中,检查互联网状态

...
HttpResponse httpResponse = httpclient.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode() == 200) //which means there is connection
     inputStream = httpResponse.getEntity().getContent();
else
     return null;

然后检查null是否离开AsyncTask ..通过提供onPostExcute和null值,并依赖null显示toast告诉用户没有Internet连接。

第二种方法

您也可以拥有一个ConnectionDetector类,在执行AsyncTask之前检查是否存在Internet连接。

public class ConnectionDetector {

private Context _context;

public ConnectionDetector(Context context){
    this._context = context;
}

public boolean isConnectingToInternet(){
    ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
      if (connectivity != null) 
      {
          NetworkInfo[] info = connectivity.getAllNetworkInfo();
          if (info != null) 
              for (int i = 0; i < info.length; i++) 
                  if (info[i].getState() == NetworkInfo.State.CONNECTED)
                  {
                      return true;
                  }

      }
      return false;
   }
}

然后在执行AysncTask

之前
 ConnectionDetector conn = new ConnectionDetector(getApplicationContext());
 if(conn.isConnectiontoInternet())
    new DownloadTextTask().execute("http://192.168.1.100/PHP_MVC/mobile/MLogin.php");
 else
    //show toast.

P.S:请务必将此权限添加到您的清单中:

<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

答案 1 :(得分:1)

你得到一个空指针异常。检查空值,然后如果得到空值,则相应地执行逻辑。最重要的是,您应该在执行网络IO之前检查是否有网络连接,以帮助防止发生这些类型的问题。

您可以按照此问题中列出的解决方案执行此操作:Detect whether there is an Internet connection available on Android

答案 2 :(得分:0)

如果InputStream in = null,则会发生这种情况。如果网络关闭,OpenHttpPOSTConnection将尝试从网络读取并将失败并抛出异常。你抓住这个。这将导致函数返回null,并且inputstream将为null。

对OpenHttpPOSTConnection的返回值进行空检查将解决此问题