应用程序可能在其主线程上做了太多工作,(Android)

时间:2014-11-12 16:32:36

标签: java android multithreading asynchronous

我试图在Android应用程序上使用IMAP获取我的电子邮件。

在LogCat中,有很多事情在发生;但是,我知道为什么我会收到这些错误。 它基本上告诉我"应用程序可能在其主线程上做了太多工作"。因此, 我试图为负责SSLSockets等的类制定异步任务。

我的界面就像用户点击“登录”按钮一样,他们应该能够在登录按钮下看到他们的电子邮件。在那之后,我在标题中收到了这个错误。我想我应该能够在我的登录功能上做一些其他事情,但我找不到它。我的代码中可能还有其他一些错误。请不要担心。我只是想立即解决这个异步问题

我希望您稍后提醒您注意登录功能。在第一个代码之后,我的LoginClient.java代码将负责打开连接,与服务器通信等。

这是我的代码:(MainActivity.java)(裁剪了一下)

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[] { "jacky@gmail.com" };        
    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("jacky@gmail.com"); //Demonstration
        password.setText("*******");
        break;
    default:

        break;
    }
}

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

}



 }

这是LoginClient.java。我会稍微裁掉那个,因为我认为我的问题中有一些不相关的部分不要混淆你。这也是因为它的背景很复杂

 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);
//  }

}

你的帮助非常棒。提前谢谢!

1 个答案:

答案 0 :(得分:0)

我在模拟器上没有遇到上述警告。可能只是你的模拟器很慢。这是我的模拟器细节

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

我建议您在打开Using host GPU选项的x86影像上运行您的应用,然后查看警告是否仍然出现。

enter image description here