0

I've been trying to call an Async method from another class, but the application seems to be constantly crashing when I do so. The Async method works when I call it from within the class. I believe I've narrowed it down to when it tries to display the message on the UI thread (toast/message box). However, every solution I've tried hasn't succeeded. Below you can see my two classes. Any help will be much-appreciated thanks.

MainActivity.java

public class MainActivity extends AppCompatActivity {

private Button mBtLaunchActivity;
private ListView listView1;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    VideoList videoList_data[] = new VideoList[]
            {
                    //new VideoList(R.drawable.weather_cloudy, "Cloudy"),
                    new VideoList(R.drawable.air_squat_icon, "Air Squat Tutorial"),
                    new VideoList(R.drawable.deadlift_icon, "Deadlift Tutorial"),
                    new VideoList(R.drawable.front_squat_icon, "Front Squat Tutorial"),
                    new VideoList(R.drawable.bicep_curl_icon, "Bicep Curl Tutorial")
            };

    VideoListAdapter adapter = new VideoListAdapter(this,
            R.layout.listview_item_row, videoList_data);


    listView1 = (ListView) findViewById(R.id.listView1);

    /*View header = (View) getLayoutInflater().inflate(R.layout.listview_header_row, null);
    listView1.addHeaderView(header);*/

    listView1.setAdapter(adapter);

    //textView userText = (textView) findViewById(R.id.txtTitle);
    //final String user = userText toString();

    listView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {

            switch (position){
                case 0:

                    System.out.println("omxplayer air_squat.mp4");
                    sendCommand("ls");
                    break;

                case 1:
                    System.out.println("omxplayer deadlift.mp4");
                    break;
                case 2:
                    System.out.println("omxplayer front_squat.mp4");
                    break;
                case 3:
                    System.out.println("omxplayer bicep_curl.mp4");
                    break;
            }

            //Intent intent = new Intent(MainActivity.this, SSHConnectionDetails.class);
            //Bundle bundle = new Bundle();
            //bundle.putString("vidoedetails", filedetails);
            //bundle.putString("videoname", filename);


            //intent.putExtras(bundle);
            //intent.putExtra("videofilename", filename);
            //intent.putExtra("vidoefiledetails", filedetails);
            //startActivity(intent);

            //System.out.println("Clicked pos " + position); // your code is here on item click
            //System.out.println("Clicked id " + id);
            //System.out.println(position);
        }
    });

}

private void sendCommand(String cmd){
    //String sshCommand = command;
    //SSHConnectionDetails scd = new SSHConnectionDetails();
    //scd.host = "";
    //SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
    //SharedPreferences sharedPref = getApplicationContext().getSharedPreferences("MyPref", 0);
    //String defaultValue = "Nothing";
    //System.out.println(getString(R.string.username));
    //String highScore = sharedPref.getString(getString(R.string.username), defaultValue);
    //String host = sharedPref.getString("host", "");
    //String user = sharedPref.getString("username", "");
    //String pass = sharedPref.getString("password", "");
    //int port = sharedPref.getInt("port", 22);

    //Sending over the connection details & command to be executed
    System.out.println("AT SEND COMMAND 1");
    SSHConnectionDetails scd = new SSHConnectionDetails();
    scd.sendCommand("host","user","pass",22,cmd);
    //Send host,user,pass,port,command to be executed in a method


    //Toast.makeText(getApplicationContext(), host + user + pass + port, Toast.LENGTH_SHORT).show();
}

private void launchActivity() {

    //launching the SSHConnectionDetails activity
    Intent intent = new Intent(this, SSHConnectionDetails.class);
    startActivity(intent);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.SSH) {
        launchActivity();
        //return true;
    }

    return super.onOptionsItemSelected(item);
}

}

SSHConnectionDetails.java

public class SSHConnectionDetails extends AppCompatActivity {

private String host;
private String user;
private String pass;
private int port;

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

    SharedPreferences sharedPref = getApplicationContext().getSharedPreferences("MyPref", 0);
    String host = sharedPref.getString("host", "");
    String user = sharedPref.getString("username", "");
    String pass = sharedPref.getString("password", "");
    int port = sharedPref.getInt("port", 22);

    EditText hostText = (EditText)findViewById(R.id.Host);
    EditText userText = (EditText)findViewById(R.id.User);
    EditText passText = (EditText)findViewById(R.id.Pass);
    EditText portText = (EditText)findViewById(R.id.Port);

    hostText.setText(host, TextView.BufferType.EDITABLE);
    userText.setText(user, TextView.BufferType.EDITABLE);
    passText.setText(pass, TextView.BufferType.EDITABLE);
    portText.setText(String.valueOf(port), TextView.BufferType.EDITABLE);

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    Toast.makeText(getApplicationContext(),host, Toast.LENGTH_SHORT).show();

    }

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        // Respond to the action bar's Up/Home button
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
    }
    return super.onOptionsItemSelected(item);
}

public void navigateUp(View view){
    NavUtils.navigateUpFromSameTask(this);
}

public void testInput2(View view){

    //Collecting the inputted connection details and assigning them to variables
    EditText userText = (EditText) findViewById(R.id.User);
    user = userText.getText().toString();
    System.out.println(user);
    EditText passText = (EditText) findViewById(R.id.Pass);
    pass = passText.getText().toString();
    System.out.println(pass);
    EditText hostText = (EditText) findViewById(R.id.Host);
    host = hostText.getText().toString();
    System.out.println(host);
    EditText portText = (EditText) findViewById(R.id.Port);
    port = Integer.parseInt(portText.getText().toString());
    System.out.println(port);

    sendCommand(host,user,pass,port,"ls");
}

public void sendCommand(final String hst, final String uname, final String pword, final int prt, final String cmd){
    System.out.println("AT SEND COMMAND 2");
    ExecuteSSHConnectionTask esct = new ExecuteSSHConnectionTask(SSHConnectionDetails.this);
    esct.execute();
}

}

ExecuteSSHConnectionTask.Java

public class ExecuteSSHConnectionTask extends AsyncTask<Integer, Void, String>{
private Context mContext;
String uname = "user";
String pword = "pass";
int prt = 22;
String hst = "host";
String cmd = "ls";

public ExecuteSSHConnectionTask(Context context){
    mContext = context;
}

ExecuteRemoteCommand erc = new ExecuteRemoteCommand(mContext);

protected String doInBackground(Integer... params) {
    try {

        erc.executeRemoteCommand(uname, pword, hst, prt, cmd);
    } catch (Exception e) {
        //displayMessage("Connection Unsuccessful: " + e.toString());
        e.printStackTrace();
    }
    return "Test";
}

    protected void onPostExecute(String result) {            
        //Toast.makeText(mContext, "Test" + result, Toast.LENGTH_SHORT).show();
        //finish();

        erc.displayMessage(result);
    }
}

class ExecuteRemoteCommand{
    private Context mContext;
    public ExecuteRemoteCommand(Context context) {
        mContext = context;
    }
public void executeRemoteCommand(
        String username,
        String password,
        String hostname,
        int port,
        String command) {
    try {
        // Setting up the session with the details provided
        JSch jsch = new JSch();
        Session session = jsch.getSession(username, hostname, port);
        session.setPassword(password);

        // Avoid asking for key confirmation
        Properties prop = new Properties();
        prop.put("StrictHostKeyChecking", "no");
        session.setConfig(prop);

        session.connect();

        // SSH Channel
        ChannelExec channelssh = (ChannelExec) session.openChannel("exec");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        channelssh.setOutputStream(baos);

        // Executing the command
        //channelssh.setCommand("ls");
        channelssh.setCommand(command);
        channelssh.connect();
        channelssh.disconnect();

        // Letting the user know that a successful connection has been made to the remote computer
        //displayMessage("Connection Successful");

    } catch (JSchException e) {
        //displayMessage("Connection Unsuccessful: " + e.toString());
    }

}

    public void displayMessage(final String in){
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                mContext);

        // set title
        alertDialogBuilder.setTitle("Your Title");

        // set dialog message
        alertDialogBuilder
                .setMessage("Click yes to exit!")
                .setCancelable(false)
                .setPositiveButton("Yes",new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,int id) {
                        // if this button is clicked, close
                        // current activity
                        //mContext.finish();
                    }
                })
                .setNegativeButton("No",new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,int id) {
                        // if this button is clicked, just close
                        // the dialog box and do nothing
                        dialog.cancel();
                    }
                });

        // create alert dialog
        AlertDialog alertDialog = alertDialogBuilder.create();

        // show it
        alertDialog.show();
    }
}

LOGCAT: https://pastebin.com/SxkNVPJ7

Assim
  • 1
  • 1
  • Can you add logcat traces? – Yogesh Lakhotia Apr 13 '17 at 16:59
  • Sure @YogeshLakhotia https://pastebin.com/k2yW5wHX – Assim Apr 13 '17 at 17:09
  • `SSHConnectionDetails scd = new SSHConnectionDetails();` .....it´s an Activity....don´t create a new instance of an activity...I guess you have some big misunderstanding here. What are you trying to do? You should exclude the method you want to call from that activity... – Opiatefuchs Apr 13 '17 at 17:43
  • @Opiatefuchs I'm trying to send connection details through to the second class so that it creates an SSH connection with the details and command sent. – Assim Apr 13 '17 at 18:42
  • You can´t do it like this. Your sendCommand() method should be in an extra non activity class.... – Opiatefuchs Apr 13 '17 at 18:44
  • @Opiatefuchs even with adding Async into a separate Java file, the problem persists. – Assim Apr 14 '17 at 01:32
  • that maybe, I hadn´t said it´s the cause. but it was definetely wrong. So, let´s go on and search for the issue...what is in line 121 in your `ExecuteSSHConnectionTask` class? – Opiatefuchs Apr 14 '17 at 04:52
  • and again, here is also a mistake: `ExecuteRemoteCommand extends Activity` ...Why you extend an Activity here? I think you have a misunderstanding from the coding basics. In simple words, an Activity is to show a user interaction screen with all the views inside etc.. A class like your `ExecuteRemoteCommand` doesn´t need to extend an activity. – Opiatefuchs Apr 14 '17 at 04:56
  • An activity is only needed to do something what you had put inside your xml layout...Textviews, buttons, layouts and so on..... – Opiatefuchs Apr 14 '17 at 04:58
  • @Opiatefuchs Line 121 is "AlertDialog alertDialog = new AlertDialog.Builder(mContext).create();". I appreciate your help as I'm new to android programming. Also, I've: Removed extends Activity from ExecuteRemoteCommand class; passed mContext to ExecuteRemoteCommand and Commented out runOnUiThread this time it doesn't crash till I click off the emulator then displays the same error message. – Assim Apr 14 '17 at 12:06
  • Plus, it doesn't display the message box. – Assim Apr 14 '17 at 13:16
  • I think create is here misplaced, Your dialog has nothing, put create at the end before show(). ANyways, I recommend to create a dialog with AlertDialog.Builder. See this simple example and follow it:https://www.mkyong.com/android/android-alert-dialog-example/ – Opiatefuchs Apr 15 '17 at 05:19
  • @Opiatefuchs I've tried using the dialog builder that you suggested and it doesn't seem to make a difference The same error is occurring on the same line "AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( mContext);". Everytime the code reaches "erc.displayMessage(result);" and it enters displayMessage method it crashes. I don't see why this is happening. – Assim Apr 16 '17 at 14:32
  • step by step my friend. As next, you are initializing ExecuteRemoteCommand on the wrong place. At this time, mContext is null. Create the global Variable `ExecuteRemoteCommand erc=null;` and inside the constructor of `ExecuteSSHConnectionTask`, after initializing context, do: `erc = new ExecuteRemoteCommand(mContext);` . If you do it like in your code, it´s just like building a new object, but the context is null. Java/Android code is not executing in order of writing... – Opiatefuchs Apr 16 '17 at 16:30
  • @Opiatefuchs I've found out partially what the problem was. The MainActivity was sending commands and connection details to the sendCommand method, without the context. So, I sent over the parameter and now it doesn't crash. The other part of the problem I also resolved, I found out that doInBackground & onPostExecute don't like referring to other methods. So I put all of the code inside doInBackground & onPostExecute. The program works fine now. Thanks for your assistance anyway, much appreciated. – Assim Apr 20 '17 at 14:36

0 Answers0