Android 如果我向远程json添加连接(然后解析),为什么此活动会挂起?

Android 如果我向远程json添加连接(然后解析),为什么此活动会挂起?,android,json,http,parsing,connection,Android,Json,Http,Parsing,Connection,我创建了以下活动,如果我向getData方法添加注释,它的负载会很好。若我删除了注释,那个么我将连接到远程url以获取和解析json数据。这似乎会降低活动的负载。 如果我在GetData调用中添加注释,它会立即加载;如果使用GetData,它将在4-5秒内加载。以下是我的活动: public class MyActivity extends Activity implements OnItemSelectedListener { Spinner method; EditText

我创建了以下活动,如果我向getData方法添加注释,它的负载会很好。若我删除了注释,那个么我将连接到远程url以获取和解析json数据。这似乎会降低活动的负载。 如果我在GetData调用中添加注释,它会立即加载;如果使用GetData,它将在4-5秒内加载。以下是我的活动:

public class MyActivity extends Activity implements OnItemSelectedListener {
    Spinner method;
    EditText amount;
    EditText address;
    EditText email;
    EditText total;
    Button sendButton;
    List<String> methods;
    String selected_method;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);

        method = (Spinner) findViewById(R.id.spinnerBuy); // Spinner element
        amount = (EditText) findViewById(R.id.editImporto);
        address = (EditText) findViewById(R.id.editAddress);
        email = (EditText) findViewById(R.id.editEmail);
        total = (EditText) findViewById(R.id.editTotale);
        sendButton = (Button) findViewById(R.id.button);

        method.setOnItemSelectedListener(this);

        methods = new ArrayList<String>();
        methods.add("Method 1");
        methods.add("Method 2");
        methods.add("Method 3");
        methods.add("Method 4");

        ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, R.layout.my_simple_spinner_item, methods);
        dataAdapter.setDropDownViewResource(R.layout.my_simple_spinner_dropdown_item);
        method.setAdapter(dataAdapter);

        try {
            getData();
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void getData() throws JSONException {
        int timeout = 10;
        String jsonString = null;

        BasicHttpParams basicParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(basicParams, timeout * 1000);
        HttpConnectionParams.setSoTimeout(basicParams, timeout * 1000 );
        DefaultHttpClient client = new DefaultHttpClient(basicParams);

        HttpGet request = new HttpGet("https://www.example.com/data.json");
        request.addHeader("Cache-Control", "no-cache");

        try {
            HttpResponse response = client.execute(request);
            HttpEntity entity = response.getEntity();
            InputStreamReader in = new InputStreamReader(entity.getContent());
            BufferedReader reader = new BufferedReader(in);
            StringBuilder stringBuilder = new StringBuilder();
            String line = "";

            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }

            jsonString = stringBuilder.toString();

        } catch (SocketTimeoutException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

问题可能是什么以及如何解决?

这是因为所有网络操作都必须在非UI线程中完成。您可以使用异步类进行如下网络操作:

 private class GetDataAsync extends AsyncTask<Void, Void, Void > {
    @Override
    protected Void doInBackground(Void... voids) {
        //Get Data
      getData();

        return null;
    }

    @Override
    protected void onPostExecute(void result) {
 //anything you want to do it on UI 
    }
}

您必须使用异步类运行网络操作。Async类有一个方法,您可以重写该方法,该方法称为doInBackground,它不在UI线程上运行

private class MyAsyncTask extends AsyncTask<String, String, String>{


    @Override
    protected String doInBackground(String... params) {

        //Here write your network request

        //to obtain result instead of returning null..return the String reply
        return reply;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        //This part runs after the async is ready, and yes this is back to the UI thread

       //s is the reply from the doInBackgroud returned value
    }
}
更新-进度条

要包含进度条,还必须覆盖onPreExecute方法..,该方法也在ui线程中运行,并在doInBackground方法之前运行..因此在preExecute上显示进度条

首先声明一个全局进度条

ProgressDialog progress;
然后是预执行方法

 @Override
    protected void onPreExecute() {
        super.onPreExecute();

        progress = ProgressDialog.show(this, "dialog title",
                "dialog message", true);
    }
并在postExecute中添加

progress.dismiss();
删除进度条的步骤

更新!!-网络连接

您可以使用此方法检查网络

public static boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager
            = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
使用


这是因为您正在进行网络操作。因此,这显然需要更长的时间。甚至是你的代码:P。你知道优化它的方法吗?@smartmouse:使用它可以工作,现在它可以立即加载。这是我第一次使用AsyncTask。。。那么现在如何将在AsyncTask中获得的值返回到主活动?我正在更新应答请参见更新的应答..在DoonBackground中以字符串形式返回应答..并将其捕获到postExecute方法抱歉,您能告诉我如何添加进度条吗?因为在值可用之前,我得到一个nullPointerException。。。我的意思是:不,请使用YourActivityName。如果您在片段中,请使用主机活动名称。这是我第一次使用AsyncTask。如何将stringBuilder的值返回到主活动?
public static boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager
            = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
if(isNetworkAvailable(context)){
   new MyAsyncTask().execute();
}else{
   //No Internet don't run task
}