2015-01-01 47 views
0

裏面我SSHsocket類(不延長或實施任何東西)我實例HandlerThread:方法返回null,但對話框顯示

 socketHandlerThread = new HandlerThread(sessionTag); 
     socketHandlerThread.start(); 

然後我調用connect()方法:

socketHandler = new Handler(socketHandlerThread.getLooper()) { 
     public void handleMessage(Message msg) { 
      switch (msg.what) { 
       case TerminalService.SERVICE_TO_SOCKET_DO_CONNECT: 
         try { 
          connect(); 
         } catch (IOException e) { 
          Message statusMsg = Message.obtain(null,SOCKET_TO_SERVICE_STATUS_DEAD, sessionDetailData.getUuid()); 
          serviceHandler.sendMessage(statusMsg); 
          Log.e("SSH Socket id:" + sessionDetailData.getUuid() + " fails. ", e.toString()); 
         } 
         break; 

裏面我需要打開一個肯定的connect()方法/無對話框:

final String titleMessage = "Do you want to accept the hostkey (type " + algo + ") from " + host + " ?\n"; 


mainActivity.runOnUiThread(new Runnable() { 
       public void run() { 
        FragmentTransaction fragmentTransaction=mainActivity.getFragmentManager().beginTransaction(); 
        AcceptKeyDialog acceptKeyDialog = new AcceptKeyDialog(); 
        acceptKeyDialog.show(fragmentTransaction, "KEY_ACCEPT_DIALOG"); 
        acceptKeyDialog.getTitleView().setText(titleMessage); 
       } 
      }); 

會發生什麼情況,即使使用按鈕,對話框也會按預期填充。但是在調試時,runOnUiThread()中的(任何地方)斷點顯示acceptKeyDialog片段實例的屬性爲null(充氣視圖,監聽器......我稱之爲控制器等)。所以顯然調用AcceptKeyDialog的getTitleView()方法也會返回null。

public class AcceptKeyDialog extends DialogFragment { 
    private View keyDialogView; 

    //inner listener class for buttons 
    private AceeptKeyDialogFragmentController controller; 

    private TextView title; 
    private Button yesButton; 
    private Button noButton; 


    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

@Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     Window window = getDialog().getWindow(); 
     window.setBackgroundDrawable(new ColorDrawable(Color.BLACK)); 

     //DialogFragment.STYLE_NO_TITLE is not working as it should 
     window.requestFeature(Window.FEATURE_NO_TITLE); 
     controller = new AceeptKeyDialogFragmentController(); 
     keyDialogView = inflater.inflate(R.layout.accept_key_dialog, container, false); 
     title = (TextView) keyDialogView.findViewById(R.id.accept_key_title); 
     yesButton = (Button) keyDialogView.findViewById(R.id.accept_key_yes_button); 
     noButton = (Button) keyDialogView.findViewById(R.id.accept_key_no_button); 

     title.setTextColor(Color.GREEN); 

     yesButton.setOnClickListener(controller); 
     noButton.setOnClickListener(controller); 

     return keyDialogView; 
    } 

    public TextView getTitleView(){ 
     return title; 
    } 

    private class AceeptKeyDialogFragmentController implements View.OnClickListener { 

     @Override 
     public void onClick(View view) { 
      switch (view.getId()) { 
       case R.id.accept_key_yes_button: 

        break; 
       case R.id.accept_key_no_button: 

        break; 
      } 
     } 
    } 

我想這可能是比使用處理器的信息(或handler.post ..或者通過消息傳遞中運行的),但很明顯,我錯過了一些在HandlerThread概念根本更好。我還以爲,這可能是一些涉及到mainActivity的通過參考其由mainActivity=(MainActivity)msg.obj

做,但我沒有看到活動狀況正在改變(監控MainActivity的onStop()方法)

@Override 
    protected void onStop(){ 
     Log.e("MainActivity is in onStop state",""); 
     super.onStop(); 
    } 

最後目標是將用戶決定傳遞迴工作線程,並根據響應繼續。你能建議嗎?

回答

0

我已經在這個問題上贏得了風滾草徽章,所以它值得回答:) 但是,答案可能有點令人失望,因爲我沒有完全理解它。我所描述的似乎是與mainActivity.runOnUiThread()方法運行的另一個線程內的Main Thread對象後向可見性有關的一般問題。正如你可以看到下面我沒有實例化一個對話框對象。相反,我在主線程方法activity.fireInteractiveDialog(args)中運行,這對我來說是這樣的。
所以我不得不停止線程爲了獲得用戶輸入,然後等待條件(以及輸入本身),使線程再次運行。這一切都是通過「保護鎖」編程構造完成的,當然HandlerThread()的實例是傳遞條件狀態的線程並通知停止的線程再次運行。 下面是代碼:

public synchronized void getUserInput() { 


      activity.runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        Bundle args = new Bundle(); 
        args.putString("somethingDialogTag", tag); 
        args.putString("somethingDialogTitle", title); 
        args.putStringArray("somethingDialogContent", content); 
        args.putBoolean("somethingDialogPassword", isPassword); 
        if (isPassword) { 
         args.putString("somethingDialogExistingPassword", sessionDetailData.getPassword()); 
        } 
        //lets open the dialog 
        activity.fireInteractiveDialog(args); 

       } 
      }); 


      while (!isInputAvailable) { 
       try { 
        Log.d("Thread " + String.valueOf(Thread.currentThread().getId()), " going to wait."); 
        wait(); 
        Log.d("Thread " + String.valueOf(Thread.currentThread().getId()), " has woke up."); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

和同類HandlerThread改變(由一個消息對象作爲攜帶)可變isInputAvailable以及提供的用戶輸入,一旦它已經準備好內部。

socketHandlerThread = new HandlerThread(tag); 
socketHandlerThread.start(); 

socketHandler = new Handler(socketHandlerThread.getLooper()) { 
      public void handleMessage(Message msg) { 

       switch (msg.what) { 
        case Bus.SERVICE_TO_SOCKET_STATUS_KEY_ACCEPTANCE: 
         isKeyAccepted = ((MessageHolder) msg.obj).getLogic(); 
         synchronized (advancedVerifier) { 
          advancedVerifier.notifyAll(); 
         } 
         Log.e(tag + "User decided to accept key", String.valueOf(((MessageHolder) msg.obj).getLogic())); 
         break; 

我希望有一天能幫助別人。如果有人瞭解線程中的對象可見性(Android主線程和工作人員),則會很好。