problems with Strictmode.Threadpolicy

Asked

Viewed 199 times

1

Hello, I have the link below

http://www.hotplateprensas.com.br/ws/clientest.php

that delivers me a string json of the kind

{
  "clientes":[
     {
       "idClientesT":"1",
       "tipo":"s",
       "nome":"Carlos"},
     {
       "idClientesT":"2",
       "tipo":"s",
       "nome":"Rogério"
     }
  ]
}

So in the AndroidStudio, manipulate her with the Classe down below:

package carcleo.com.radiosingular;

import android.os.Bundle;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

import carcleo.com.radiosingular.classes.Clientes;
import carcleo.com.radiosingular.classes.JsonClass;

public class form extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.form);
    }

    public void listaClientes (View View) {

        if (android.os.Build.VERSION.SDK_INT > 9){
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

        String url = "http://hotplateprensas.com.br/ws/clientest.php";
        JsonClass json = new JsonClass();
        ArrayList<Clientes> clientesLista = json.getJSONFromUrl(url);

        Log.v("Cliente 2", clientesLista.get(1).getNome());

    }

}

That one código works normally. However, you need to put the code snippet below;

if (android.os.Build.VERSION.SDK_INT > 9){
   StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
   StrictMode.setThreadPolicy(policy);
}

Otherwise, the internet connection is NOT established. 

However, I have already added the permission to access the INTERNET on AndroidManifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="carcleo.com.radiosingular">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".login">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".form" />
    </application>

</manifest>

But it’s no use.

If I remove that code block

if (android.os.Build.VERSION.SDK_INT > 9){
   StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
   StrictMode.setThreadPolicy(policy);
}

The connection with the INTERNET doesn’t happen.

The problem is, if I work like this, how many times do I need to access INTERNET will be the same number of times I will have to make use of this code snippet.

Is there not a general configuration file for this in AndroidStudio?

Follows the classe Jsonclass:

package carcleo.com.radiosingular.classes;

import android.util.Log;
import android.widget.Toast;

import com.google.gson.JsonArray;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.util.ArrayList;

import cz.msebera.android.httpclient.HttpEntity;
import cz.msebera.android.httpclient.HttpResponse;
import cz.msebera.android.httpclient.client.ClientProtocolException;
import cz.msebera.android.httpclient.client.methods.HttpPost;
import cz.msebera.android.httpclient.impl.client.DefaultHttpClient;

public class JsonClass {

    InputStream input = null;
    JSONObject jObect = null;
    String json = "";

    //Recebe sua url
    public ArrayList<Clientes> getJSONFromUrl(String url) {
        //HTTP request
        try {
            // default HttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            input = httpEntity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;

            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }

            input.close();

            json = sb.toString();//

            // Transforma a String de resposta em um JSonObject
            jObect = new JSONObject(json);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        // retorna o objeto
        return Clientes(jObect);

    }

    private ArrayList<Clientes> Clientes (JSONObject jObect) {
       // Cria o Array List de Clientes
        ArrayList<Clientes> aCli = null;

        try {

            aCli = new ArrayList<>();
            //Pega o primeiro índice do Array de Objetos, no caso, o array Clientes
            JSONArray clientesLista = jObect.getJSONArray("clientes"); // aqui você faz o resgate da lista

            // Transforma a JSONArray de resposta em um Array de objjeo da Classe Clientes
            for (int i = 0; i < clientesLista.length(); i++) {
                //Pega cada íncide do array e atribui a uma variável
                JSONObject jSobj = clientesLista.getJSONObject(i);
                //Indetifica os campos do objeto
                int id =  Integer.parseInt(jSobj.getString("idClientesT"));
                //int id =  jSobj.getInt("idClientesT");
                String tipo = jSobj.getString("tipo");
                String nome = jSobj.getString("nome");
               //popula o objeto da classe de clientes
                Clientes cliente = new Clientes(id, tipo, nome);
                //Adiciona o objeto de Classe criado ào Array de Clientes
                aCli.add(cliente);
            }

        } catch (JSONException e) {
            Log.e("JSON Parser", "Erro no parsing doo objeto " + e.toString());
        }
        //Retorno o array de Clientes.
        return aCli;

    }

}

1 answer

1

What happens is that your JsonClass tries to access the network (a blocking operation) in the main thread of Android, which is not allowed.

You can read a little more on the subject at this link, but to summarize: The main thread of Android is responsible for updating the views.

Doing blocking tasks like accessing the network or database on this thread causes the view to lock, giving the impression of lag in the app.

The link above, inclusive, gives an alternative to solve this problem: do this kind of tasks within Asynctasks.


I personally prefer to delegate all this work to libraries like the Retrofit.

Doing what you want with this lib is quite trivial:

After adding dependencies, define the contract in an interface:

public interface HotPlateService {
  @GET("clientest.php")
  Call<List<Clientes>> listClientes();
}

Starts the service instance:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("http://www.hotplateprensas.com.br/ws/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

HotPlateService service = retrofit.create(HotPlateService.class);

And to consume the service in a non-blocking way, just call:

service.listClientes().enqueue(new Callback<List<Clientes>>() {
  @Override public void onResponse(Call<List<Clientes>> call, Response<List<Clientes>> response) {

  }

  @Override public void onFailure(Call<List<Clientes>> call, Throwable t) {

  }
});

Now, into the callback onResponse you already have the answer of the parsed webservice and ready to use.

  • But, tell me something. What’s better? A) Make a common class and extend Asynctask, B) use Retrofit or 3) Use Volley?

  • V/Wrong:: java.lang.Illegalstateexception: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

Browser other questions tagged

You are not signed in. Login or sign up in order to post.