-4

Well, i dont know why, but my app is crahing everytime I am hiting the submit button in the login Activity. The Main Activity works fine...

My Login Activity:

package de.blender4me.einkaufsliste;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class LoginActivity extends Activity {

EditText password;
EditText username;
Button submit;
TextView userPass;

String usernameString;
String passwordString;


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

    submit = (Button) findViewById(R.id.buttonSubmitLogin);
    submit.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            password = (EditText) findViewById(R.id.editTextPassword);
            passwordString = password.getText().toString();

            username = (EditText) findViewById(R.id.editTextUsername);
            usernameString = username.getText().toString();

            userPass = (TextView) findViewById(R.id.textPassUser);

            LongOperation lo = new LongOperation();
            lo.execute();
        }
    });
}

@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();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);



}
private class LongOperation extends AsyncTask<Void, Void, String> {

    private String[] values = null;

    @Override
    protected String doInBackground(Void... params) {
        internetHandler ih = new internetHandler();
        values = ih.getList(usernameString,passwordString,"","");

        userPass.setText(values[0]);

        if(!values[0].equalsIgnoreCase("error")&&!values[0].equalsIgnoreCase("401")&&!values[0].equalsIgnoreCase("404")){
            userPass.setText("Yep");
        }else{
            userPass.setText(values[0]);
        }

        return null;
    }

    @Override
    protected void onPostExecute(String result) {
    }   
  }
}

My Main Activity:

package de.blender4me.einkaufsliste;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;


public class MainActivity extends Activity {

//Widgets
Button addItem;
Button loginMenu;



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

        //listView
        LongOperation lo = new LongOperation();
        lo.execute();

        //register Widgets
        addItem =(Button) findViewById(R.id.addItem);
        addItem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openDialog();
            }
        });

        loginMenu = (Button) findViewById(R.id.loginMenu);
        loginMenu.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent(getApplicationContext(), LoginActivity.class);
                startActivity(i);
            }
        });
    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.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();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

//Alert
public void openDialog(){
    AlertDialog.Builder alert = new AlertDialog.Builder(this);

    alert.setTitle("Zur Einkaufsliste hinzufügen");
    alert.setMessage(" ");

    // Set an EditText view to get user input 
    final EditText input = new EditText(this);
    alert.setView(input);

    alert.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
      String value = input.getText().toString();
      // Do something with value!
      }
    });

    alert.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int whichButton) {
        // Canceled.
      }
    });

    alert.show();
}

//listView erstellen
private class LongOperation extends AsyncTask<Void, Void, String> {

    private String[] values = null;

    @Override
    protected String doInBackground(Void... params) {
        internetHandler ih = new internetHandler();
        values = ih.getList("TestUser","TestPass","TestValue","");
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        //Liste konvertieren
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, 
            R.layout.listview_item, //Genutztes Layout
            values); //Genutzter Array

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

    @Override
    protected void onPreExecute() {}

    @Override
    protected void onProgressUpdate(Void... values) {}
  }
}

My internetHandler:

package de.blender4me.einkaufsliste;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Pattern;

public class internetHandler {

    //Einkaufsplaner-API aufrufen
        public static String[] getList(String name, String pass, String addValue, String removeValue){

            InputStream is = null;

            try
            {
              URL url = new URL("https://einkaufsplaner.blender4me.de/api.php?name="+name+"&pass="+pass+"&addValue="+addValue+"&removeValue="+removeValue);
              BufferedReader in = new BufferedReader(
              new InputStreamReader(url.openStream()));

              String Values = null;

              for(int i = 0; i < 4; ++i){
                  Values = in.readLine();
              }
              in.close();

              String[] List = Values.split( Pattern.quote( ";" ) );
              return List;

            }
            catch ( Exception e ) {
              e.printStackTrace();
            }
            finally {
              if ( is != null )
                try { is.close(); } catch ( IOException e ) { }
            }
            String[] error = {"error"};
            return error;
        }
}

Error:

11-07 21:34:29.474: E/Trace(1223): error opening trace file: No such file or directory (2) 11-07 21:34:32.785: D/gralloc_goldfish(1223): Emulator without GPU emulation detected. 11-07 21:34:34.074: D/dalvikvm(1223): GC_CONCURRENT freed 260K, 10% free 7393K/8135K, paused 16ms+15ms, total 59ms 11-07 21:34:39.964: I/Choreographer(1223): Skipped 248 frames! The application may be doing too much work on its main thread. 11-07 21:34:40.504: W/dalvikvm(1223): threadid=12: thread exiting with uncaught exception (group=0x40a13300) 11-07 21:34:40.564: E/AndroidRuntime(1223): FATAL EXCEPTION: AsyncTask #2 11-07 21:34:40.564: E/AndroidRuntime(1223): java.lang.RuntimeException: An error occured while executing doInBackground() 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.os.AsyncTask$3.done(AsyncTask.java:299) 11-07 21:34:40.564: E/AndroidRuntime(1223): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 11-07 21:34:40.564: E/AndroidRuntime(1223): at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 11-07 21:34:40.564: E/AndroidRuntime(1223): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 11-07 21:34:40.564: E/AndroidRuntime(1223): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 11-07 21:34:40.564: E/AndroidRuntime(1223): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 11-07 21:34:40.564: E/AndroidRuntime(1223): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 11-07 21:34:40.564: E/AndroidRuntime(1223): at java.lang.Thread.run(Thread.java:856) 11-07 21:34:40.564: E/AndroidRuntime(1223): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4609) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:835) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.view.View.requestLayout(View.java:15129) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.view.View.requestLayout(View.java:15129) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.view.View.requestLayout(View.java:15129) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.view.View.requestLayout(View.java:15129) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:292) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.view.View.requestLayout(View.java:15129) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.widget.TextView.checkForRelayout(TextView.java:6309) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.widget.TextView.setText(TextView.java:3547) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.widget.TextView.setText(TextView.java:3405) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.widget.TextView.setText(TextView.java:3380) 11-07 21:34:40.564: E/AndroidRuntime(1223): at de.blender4me.einkaufsliste.LoginActivity$LongOperation.doInBackground(LoginActivity.java:71) 11-07 21:34:40.564: E/AndroidRuntime(1223): at de.blender4me.einkaufsliste.LoginActivity$LongOperation.doInBackground(LoginActivity.java:1) 11-07 21:34:40.564: E/AndroidRuntime(1223): at android.os.AsyncTask$2.call(AsyncTask.java:287) 11-07 21:34:40.564: E/AndroidRuntime(1223): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 11-07 21:34:40.564: E/AndroidRuntime(1223): ... 5 more 11-07 21:34:42.315: I/Process(1223): Sending signal. PID: 1223 SIG: 9

Kara
  • 6,115
  • 16
  • 50
  • 57
Alaska
  • 309
  • 1
  • 4
  • 9
  • You can't access the UI in `doInBackground()` -- that's what `onPostExecute()` is for. If you had clicked on the exception in your logcat, it would have taken you to `userPass.setText`... – 323go Nov 07 '14 at 21:49
  • possible duplicate of [Android "Only the original thread that created a view hierarchy can touch its views."](http://stackoverflow.com/questions/5161951/android-only-the-original-thread-that-created-a-view-hierarchy-can-touch-its-vi) – ToYonos Nov 07 '14 at 23:24

1 Answers1

0

Actually, you are trying to update Application UI from doInBackground() of AsyncTask which cause this errors.

So change your code look like,

@Override
protected String doInBackground(Void... params) {
    internetHandler ih = new internetHandler();
    values = ih.getList(usernameString,passwordString,"","");
    return values[0];    
}

@Override
protected void onPostExecute(String result) {
   if(!result.equalsIgnoreCase("error") && !result.equalsIgnoreCase("401") && !result.equalsIgnoreCase("404")){
        userPass.setText("Yep");
    }else{
        userPass.setText(result);
    }
}   

As doInBackground() runs in worker thread so you can not access android's Main Application UI thread from it, For that you have to update your UI part from onPostExecute() which runs on UI thread.

user370305
  • 108,599
  • 23
  • 164
  • 151