0
votes

I'm trying to fetch my e-mails using IMAP on Android application.

In LogCat, there are a lot of things going on; however, I know why I'm getting those errors. It basically tells me "the application may be doing too much work on its main thread". Hence, I was trying to formulate an asynchronous task for my class responsible for SSLSockets etc.

My interface is like when users hit Login button, they should be able to see their emails under the login button. After that, I'm getting that error in the title. I think I should be able to do something else wrapping around my Login function, but I couldn't find it. There might be some other errors in my code. Please don't worry about it. I just want to fix that asynchronous issue right now

I'd like you to call your attention to the login function a bit below. After the first code, there will be my LoginClient.java code liable for opening connection, communicating with server etc.

Here is my code: (MainActivity.java) (Cropped a bit)

package com.theOwl.android_imap;

import java.util.ArrayList;

import android.app.Activity;
-------------


public class MainActivity extends Activity implements OnItemSelectedListener{

EditText servername, port, username, password;
Spinner dropdown;
Button blogin;

public static ArrayList<String> listModel = new ArrayList<String>();

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

    servername = (EditText) findViewById(R.id.servername);
    port = (EditText) findViewById(R.id.port);
    username = (EditText) findViewById(R.id.username);
    password = (EditText) findViewById(R.id.password);
    dropdown = (Spinner) findViewById(R.id.sp1);
    blogin = (Button) findViewById(R.id.button);

    populateListView();
//  clickListView();

    String[] items = new String[] { "[email protected]" };        
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(
            MainActivity.this, android.R.layout.simple_spinner_item, items);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    dropdown.setAdapter(adapter);
    dropdown.setOnItemSelectedListener(this);

    blogin.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            login();
        }
    });
}

public void login(){
    String servernameStr = servername.getText().toString();
    String portStr = port.getText().toString();
    String usernameStr = username.getText().toString();
    String passwordStr = password.getText().toString();


    new LoginClient().execute(servernameStr, portStr, usernameStr, passwordStr);

    //Toast.makeText(MainActivity.this, mySSL_Connection.Mails.size(), 1500).show();

    /*for (int i = 0; i < mySSL_Connection.Mails.size(); i++) {
        //Placing each e-mail in the given format into the ListModel
        listModel.add(mySSL_Connection.Mails.get(i));

    }*/
    //Toast.makeText(MainActivity.this, listModel.get(0), 1500).show(); 
}


private void populateListView() {
    // TODO Auto-generated method stub

    for(int i=0; i<10; i++){
        listModel.add("email");
    }

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            R.layout.items, listModel);

    ListView list = (ListView) findViewById(R.id.listView);
    list.setAdapter(adapter);
}

/*private void clickListView() {
    // TODO Auto-generated method stub
    ListView list = (ListView) findViewById(R.id.listView);
    list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            // TODO Auto-generated method stub

            String servernameStr = servername.getText().toString();
            String portStr = port.getText().toString();
            String usernameStr = username.getText().toString();
            String passwordStr = password.getText().toString();

            String eMailBody = mySSL_Connection.getEmailBody(servernameStr, portStr, usernameStr, passwordStr, position);

            Body b = new Body();                
            b.body.setText(eMailBody);              
            startActivity(new Intent("android.intent.action.BODY"));

            switch (position) {
            case 0:
                Toast.makeText(MainActivity.this, "e-mail 1", 1500).show();
                break;
            case 1:
                Toast.makeText(MainActivity.this, "e-mail 2", 1500).show();
                break;
            case 2:
                Toast.makeText(MainActivity.this, "e-mail 3", 1500).show();
                break;
            default:

                break;
            }
        }
    });
}*/

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
        long id) {
    // TODO Auto-generated method stub
    switch (position) {
    case 0:
        servername.setText("imap.gmail.com");
        port.setText("993");
        username.setText("[email protected]"); //Demonstration
        password.setText("*******");
        break;
    default:

        break;
    }
}

@Override
public void onNothingSelected(AdapterView<?> parent) {
    // TODO Auto-generated method stub

}



 }

Here is LoginClient.java. I'm going to crop that one a bit since I think there are some unrelated parts about my question not to confuse you. That's also because its background is complicated

 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;

 import android.os.AsyncTask;

 public class LoginClient extends AsyncTask<String, Integer, String>{


 private String response;
 public List<String> Mails;
 public String [] emailBody;
 public String emre ="";

//LoginClient Constructor with four parameters

protected String doInBackground(String... params) {     
    /* open SSLSocket connection to server, send login, do the other necessary steps to
     obtain the e-mails in the server (Subject From Date)
     */
    try {

        // obtain SSLSocketFactory for creating SSLSockets
        SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory
                .getDefault(); // To be able to create SSL Sockets to secure
                                // the exchange
        System.out.println("Im here for the first time!");
        // create SSLSocket from factory
        SSLSocket socket = (SSLSocket) socketFactory.createSocket(
                params[0], Integer.parseInt(params[1]));
        System.out.println("Im here for the second time!");

        // create BufferedReader for reading server response
        BufferedReader input = new BufferedReader(new InputStreamReader(
                socket.getInputStream()));
        System.out.println("Im here for the third time!");

        // create PrintWriter for sending login, selecting folder, fetching e-mails
        PrintWriter output = new PrintWriter(new OutputStreamWriter(
                socket.getOutputStream()));
        System.out.println("Im here for the fourth time!");

        // This conversion is needed from Char[] to String
        String newpassword = new String(params[3]);
        System.out.println("Im here for the fifth time!");

        // Authentication requested after Handshake
        String login = "tag login " + params[2] + " " + newpassword;
        System.out.println("Im here for the sixth time!");

        // Send the request to server
        output.print(login + "\r\n");
        output.flush(); // Flush is to make sure that we send requests to server besides using 'print' function
        System.out.println("Im here for the seventh time!");
        /* There are more than input.readLine()s since we need to skip some lines 
         * This logic exists in the other parts of the entire code
         * depending on some logic
         * */

        response = input.readLine();
        System.out.println("Im here for the eighth time!");
        response = input.readLine();
        response = input.readLine();

        ************** //THIS MEANS I CROPPED THE CODE. WE HAVE NOTHING TO DO WITH THIS PART


        System.out.println("System successfully initiated!");
        // Clean up streams and SSLSocket
        output.close();
        input.close();
        socket.close();

    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();

        System.out.println("Program Terminates");
    }


    for (int i = 0; i < Mails.size(); i++){
        emre += Mails.get(i) + "$";
    }
    return emre;

}

   //THIS FUNCTION BELOW IS AUTOMATICALLY INVOKED AFTER doInBackground FUNCTION IS DONE

protected void onPostExecute(String result) { 
    /* "Invoked on the UI (User Interface) thread after the background 
computation finishes. The result of the background computation passed to this step 
    as a parameter resulting in showing the result */
    //for( int i = 0; i < emre.length(); i++ ){
        MainActivity.listModel.add(emre);
//  }

}

Your help would be highly great. Thanks in advance!

1
Can you rephrase your question? Is your Async working or not?StoneBird
About syntax, Im not getting any errors if that's what you mean, StoneBird. That's also because I'm able to fall into my LoginClient class, doInBackground function without any problem.Ozan Goylusun
StoneBird, though I'm getting that error (The application may be doing too much). I would appreciate if you could come up with any suggestions. If you want, I can share the whole codeOzan Goylusun
@OzanGoylusun This seems fairly obvious... You're doing too much work in the main/UI thread.Stephen Tetreault
@SMT, how can I fix that issue? I mean I kind of need a tangible help. How could it get fixed by looking into the code?Ozan Goylusun

1 Answers

0
votes

I don't experience the warning described above on my emulator. It's probably just your emulator is slow. Here is my emulator detail

CPU/ABI: Intel Atom (x86)
Target: Android 4.0.3 (API level 15)
Skin: 320x480
SD Card: 200M
hw.lcd.density: 160
disk.dataPartition.size: 200M
hw.gpu.enabled: yes
hw.ramSize: 512
tag.display: Default
hw.sdCard: yes
hw.device.manufacturer: Generic
hw.device.name: 3.2in QVGA (ADP2)
vm.heapSize: 16

And I suggest you to run your app on an x86 image with Using host GPU option turned on, and then see if the warning still comes up.

enter image description here