2016-03-28 2 views
0

Я разрабатываю приложение для Android, которое перенаправляет сумму MD5, созданную из int.Получение int в поток пользовательского интерфейса

Грубая форсирующая деталь отлично работает. (Я могу sysout окончательное значение и это правильно.)

У меня проблемы с получением выходного значения в диалоговом окне предупреждения. Logcat говорит: Attempting to initialize hardware acceleration outside of the main thread, aborting

Он прерывает последнее заявление в моем коде, которое фактически показывает диалоговое окно предупреждения;

builder.show(); 

Вот мой MainActivity.java:

import android.app.Activity; 
import android.app.AlertDialog; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Looper; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.inputmethod.InputMethodManager; 
import android.widget.EditText; 
import android.widget.RadioButton; 
import android.widget.Toast; 

import java.io.UnsupportedEncodingException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 

public class MainActivity extends Activity { 

    String passwordToHash; 
    String result; 
    boolean goodPIN = false; 
    boolean startbruteforce = false; 

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

    @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.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    //My stuff 

    public void doIt(View v) throws NoSuchAlgorithmException, UnsupportedEncodingException 
    { 
     RadioButton r2 = (RadioButton) findViewById(R.id.calculate); 
     RadioButton r1 = (RadioButton) findViewById(R.id.crack); 

     final EditText input = (EditText) findViewById(R.id.inputTextArea); 
     final EditText output = (EditText) findViewById(R.id.outputTextArea); 

     //Toast.makeText(this, "Working on it!", Toast.LENGTH_LONG).show(); 

     if(r2.isChecked()) 
     { 
      if(input.getText().toString().length() > 4) 
      { 
       goodPIN = false; 
       output.setText(""); 
       AlertDialog.Builder builder = new AlertDialog.Builder(this); 
       builder.setTitle ("Uuuuuuhh...."); 
       builder.setMessage("Hash not calculated because that PIN would take too long to brute force :("); 
       builder.setPositiveButton("Yeah, whatever...", null); 
       builder.show(); 
      } 
      else 
      { 
       goodPIN = true; 
      } 

      if(goodPIN) 
      { 
       View view = this.getCurrentFocus(); 
       if (view != null) { 
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 
       } 

       Toast.makeText(this, "Calculated MD5!", Toast.LENGTH_LONG).show(); 

       passwordToHash = input.getText().toString(); 

       MessageDigest digest = MessageDigest.getInstance("MD5"); 

       byte[] inputBytes = passwordToHash.getBytes("UTF-8"); 

       byte[] hashBytes = digest.digest(inputBytes); 

       StringBuffer stringBuffer = new StringBuffer(); 
       for (int i = 0; i < hashBytes.length; i++) 
       { 
        stringBuffer.append(Integer.toString((hashBytes[i] & 0xff) + 0x100, 16) 
          .substring(1)); 
       } 

       result = stringBuffer.toString(); 

       output.setText(result); 
      } 
     } 


     else if(r1.isChecked()) 
     { 
      View view = this.getCurrentFocus(); 
      if (view != null) { 
       InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
       imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 
      } 

      final ProgressDialog dialog = ProgressDialog.show(MainActivity.this, "Working on it!", "Brute-forcing. Please wait...", true); 
      double starttime = System.currentTimeMillis(); 

      final Thread thread = new Thread() 
      { 
       @Override 
       public void run() 
       { 
        String crackedPassword = "Hello"; 
        String crackedPasswordHash = "a262"; 
        int pinsTested = 1000; 
        int crackedPasswordInt = 1000; 
        String passwordToCrack; 

        //Get the password to crack 
        passwordToCrack = input.getText().toString(); 

        long startTime = System.currentTimeMillis(); 

        while (!crackedPasswordHash.equals(passwordToCrack)) 
        { 
         pinsTested++; 
         crackedPasswordInt++; 
         crackedPassword = Integer.toString(crackedPasswordInt); 

         MessageDigest digest = null; 
         try 
         { 
          digest = MessageDigest.getInstance("MD5"); 
         } 
         catch (NoSuchAlgorithmException e) 
         { 
          e.printStackTrace(); 
         } 

         byte[] inputBytes = new byte[0]; 
         try 
         { 
          inputBytes = crackedPassword.getBytes("UTF-8"); 
         } 
         catch (UnsupportedEncodingException e) { 
          e.printStackTrace(); 
         } 

         byte[] hashBytes = digest.digest(inputBytes); 

         StringBuffer stringBuffer = new StringBuffer(); 
         for (int i = 0; i < hashBytes.length; i++) 
         { 
          stringBuffer.append(Integer.toString((hashBytes[i] & 0xff) + 0x100, 16) 
            .substring(1)); 
         } 

         crackedPasswordHash = stringBuffer.toString(); 

         //System.out.println(pinsTested + " PINs tested"); 
         //System.out.println("Hash of: " + pinsTested + " is: " + crackedPasswordHash); 
        } 
        long endTime = System.currentTimeMillis(); 
        long totalTime = endTime - startTime; 

        System.out.println("Done! " + pinsTested); 

        updateUI(pinsTested); 

        //runOnUiThread(pinsTested); 
       } 
      }; 

      Thread animation = new Thread() 
      { 
       @Override 
       public void run() 
       { 
        try 
        { 
         Thread.sleep(4000); 
        } 
        catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 

        dialog.dismiss(); 
        thread.start(); 
       } 
      }; 

      animation.start(); 

     } 
    } 

    public void updateUI(final int pass) { 

     Looper.prepare(); 
     final Handler myHandler = new Handler(); 
      (new Thread(new Runnable() { 

       @Override 
       public void run() { 
        myHandler.post(new Runnable() { 
         @Override 
         public void run() { 
          test(pass); 
         } 
        }); 
       } 
     })).start(); 
    } 

    public void test(int pass) 
    { 
     AlertDialog.Builder builder = new AlertDialog.Builder(this); 
     builder.setTitle ("Done!"); 
     builder.setMessage("PIN is: " + pass); 
     builder.setPositiveButton("Yeah, whatever...", null); 
     builder.show(); 
    } 
} 

ответ

1

Как UI Thread говорит: для перемещения данных из фонового потока в поток пользовательского интерфейса, используйте обработчик, который работает в потоке пользовательского интерфейса.
Вы создаете обработчик в методе updateUI, но updateUI создается в потоке, отличном от потока пользовательского интерфейса, поэтому вы получаете ошибку.
Вы должны попробовать так:

public class MainActivity extends Activity { 
    private Handler mHandler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      super.handleMessage(msg); 
      switch (msg.what) { 
       case 1: 
       test((int)msg.obj); 
      } 
     } 
    } 

    public void updateUI(final int pass) { 
     Message msg = Message.obtain(); 
     msg.what=1; 
     msg.obj = pass; 
     mHandler.sendMessage(msg); 
    } 
} 
0

вы можете сделать все, что у хочу в внутри метода выполнения: , но его не очень безопасно!

runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 

     } 
    }); 
1

Согласно документации,

обработчиком позволяет передавать и обрабатывать сообщения и Runnable объекты, связанные с MessageQueue потока. Каждый экземпляр Handler связан с одним потоком и очередью сообщений этого потока. Когда вы создаете нового обработчика, он привязан к очереди потоков/сообщений потока, который его создает - с этой точки он будет доставлять сообщения и исполняемые файлы в очередь сообщений и выполнять их по мере их выхода из сообщения очередь.

Таким образом, вы создаете обработчик в методе «updateUI» и этот метод вызывается из потока, отличного от потока пользовательского интерфейса, в этом случае вам нужно объявить Handler как переменную и инициализировать обработчик в метод onCreate.

Handler

+0

Не могли бы вы объяснить немного о том, как сделать это? (Мои предыдущие приложения только что использовали основной поток, поэтому я новичок в этой многопоточной вещи) –

+0

[Пример обработчика] (https://examples.javacodegeeks.com/android/core/os/handler/android-handler- пример /) - вот хороший пример. – willermo

Смежные вопросы