0

I used AsyncTask to verify server availability.

class RetrieveFeedTask extends AsyncTask<String, String, Map<String, String>> {

    private Exception exception;
    ArrayList<String> str = new ArrayList<String>();
    Map<String, String> statusMap = new HashMap<>();

    private String job;
    public ReturnData returnData;
    public HomeFragment homeFragment = new HomeFragment();
    public AsyncResponse delegate;
    Socket socket = null;

    public void params(String job){
        this.job = job;
    }

    public void setAsyncResponse(AsyncResponse deletate){
        this.delegate = deletate;
    }


    @Override
    protected Map<String, String> doInBackground(String... params){

        //ports: 8080 5060,5070,5080
        if(job.equals("checkConn")) {

            statusMap.clear();

            boolean reachable = true;
            boolean wwwServ = true;
            try {
                InetAddress address = InetAddress.getByName(params[0]);
                reachable = address.isReachable(10000);
                Log.d("lab", "IP: "+ reachable);
            } catch (Exception e){
            }
            try {
                (new Socket(params[0], 8080)).close();
            }
            catch (UnknownHostException e)
            {
                wwwServ = false;
            }
            catch (IOException e)
            {
                wwwServ = false;
            }
            Log.d("lab", "WWW: " + wwwServ);
            Log.d("lab", "Rozmiar listy: " + Integer.toString(str.size()));
            //add values to map
            statusMap.put("IP", Boolean.toString(reachable));
            statusMap.put("WWW", Boolean.toString(wwwServ));
        }
         return statusMap;
    }
    @Override
    protected void onPostExecute(Map<String, String> result) {
        // Result is here now, may be 6 different List type.
        Log.d("lab", "The returned list contains " +result.size()+ "elements");
        delegate.processFinish(result);
    }

}

AsyncTask returns the map. Everything was ok until I ran it as a function of onCreateView. A problem arose as making moved to the onClick function. I did this because, the status update only if a user clicked on the card, rather than on the button.

public class HomeFragment extends Fragment implements AsyncResponse{

    Button checkConn;
    TextView statusIP,statusWWW;
    SharedPreferences savedSettings;
    SharedPreferences.Editor editor;
    private ArrayList<String> lista = new ArrayList<String>();
    private Map<String, String> statusMap = new HashMap<>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {


        final RetrieveFeedTask task = new RetrieveFeedTask();
        task.setAsyncResponse(this);
        task.params("checkConn");

        savedSettings = getActivity().getSharedPreferences("lab.linuxservice.com.linuxservice", Context.MODE_PRIVATE); //load shared preferences
        editor = savedSettings.edit();

        View rootView = inflater.inflate(R.layout.fragment_home, container, false);

        statusIP = (TextView)rootView.findViewById(R.id.ipStatusText);
        statusWWW = (TextView)rootView.findViewById(R.id.sipServerStatusText);

        checkConn = (Button) rootView.findViewById(R.id.checkConn);
        checkConn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)   {

                Log.d("lab", "Rozmiar listy w onCreateView: " + Integer.toString(statusMap.size()));

                String data[] = {savedSettings.getString("IP", "")};
                task.execute(data); //chceck connection on click

                String ipStatus = statusMap.get("IP");
                String wwwStatus = statusMap.get("WWW");

                Log.d("lab", "ipStatus: " + ipStatus);

                if(ipStatus.equals("false")){
                    statusIP.setText("Unavailable");
                 }
                else{
                    statusIP.setText("Available");
                }

                if(wwwStatus.equals("false")){
                    statusWWW.setText("Unavailable");
                }
                else{
                    statusWWW.setText("Available");
                }

                Toast.makeText(getActivity(), "Checking: ", Toast.LENGTH_SHORT).show();


            }
        });

        return rootView;
    }

    public void processFinish(Map<String, String> output) {
        this.statusMap = output;
    }
}

How do I start AsyncTask in onClick- get this error:

 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
            at lab.linuxservice.com.linuxservice.HomeFragment$1.onClick(HomeFragment.java:132)

The line indicates on:

if(ipStatus.equals("false"))

When I wait 9 sec Thread.sleep(9000); Log.d("lab", "ipStatus wolam: " + ipStatus); ipStatus in null, when I click button second time ipStatus is not null, is true.

UPDATE

I make like this:

  public  TextView statusIP,statusWWW;

 @Override
    protected void onPostExecute(Map<String, String> result) {
        // Result is here now, may be 6 different List type.
        Log.d("lab", "The returned list contains " + result.size() + "elements");
        delegate.processFinish(result);
        homeFragment.updateView(view,result);

        String ipStatus = statusMap.get("IP");
        String wwwStatus = statusMap.get("WWW");

        Log.d("lab", "ipStatus wolam: " + ipStatus);

        statusIP = (TextView)view.findViewById(R.id.ipStatusText);


        if(ipStatus.equals("false")){
            statusIP.setText("Unavailable");
        }
        else{
            statusIP.setText("Available");
        }
        if(wwwStatus.equals("false")){
            statusWWW.setText("Unavailable");
        }
        else{
            statusWWW.setText("Available");
        }
        Log.d("lab","wykonuje onPostExecute");


    }

In RetrieveFeedTask but, a get an error:

   java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
lukassz
  • 3,135
  • 7
  • 32
  • 72
  • The code after `task.execute(data);` is likely to be executed before the task finishes and call your `AsyncResponse` delegate. Move this code to the task's `onPostExecute` or your `AsyncResponse`'s `processFinish`. – Ahmed Khalaf Jul 18 '15 at 10:57
  • Yes, but how to do so as not to present any data in the function `onPostExecute`. Just do it in a separate function - `onClick` – lukassz Jul 18 '15 at 11:02
  • When I wait 9 sec `Thread.sleep(9000); Log.d("lab", "ipStatus wolam: " + ipStatus);` `ipStatus` in null, when I click button second time `ipStatus` is not null, is true. – lukassz Jul 18 '15 at 11:07
  • Almost **NEVER** do that `Thread.sleep` thing unless you are **obliged** to. Think for a while about needed changes to move the code to the `onPostExecute` or the `AsyncResponse` method. – Ahmed Khalaf Jul 18 '15 at 11:33
  • Approx. I'll write a method that will update the view and it call in `onPostExecute` – lukassz Jul 18 '15 at 12:23

1 Answers1

0

You are getting this error because the ipStatus variable is null. Set the value of this variable once your AsyncTask finishes and provides you a status map. That means moving the line String ipStatus = statusMap.get("IP"); to the onPostExecute() method of the AsyncTask.

Price
  • 2,683
  • 3
  • 17
  • 43
  • It's about writing function in a class `HomeFragment` that will be update view, and call it in `onPostExecute`? – lukassz Jul 18 '15 at 12:29
  • Yeah. You can even provide an interface to your AsyncTask that your fragment can implement to be notified that the onPostExecute method has been reached and now you are free to use ipStatus variable since it is not null anymore. Here is an example: http://stackoverflow.com/a/9963705/3060087 – Price Jul 18 '15 at 14:16