2014-03-26 36 views
0

在實現Thread/Handler/Looper意識形態以通過傳遞消息在後臺處理信息時遇到一些響應問題。我真的不想使用AsyncTask類,因爲我已經知道如何使用它來完成我正在嘗試做的事情。使用Thread/Handler/Looper作爲工作線程Android

有人能幫助我使用下面的代碼使用GooglePlayServicesUtil類下載Apache許可證並將其顯示在DialogFragment中的TextView中嗎?

我最大的問題是,當我啓動它時,它有時很快,但其他人顯示DialogFragment速度很慢。也許我沒有按照加載DialogFragment的最佳做法,我真的不知道。

更新 添加了現在正在運行的代碼,但由於某種原因,我仍然在一段時間內得到了UI凍結。 有誰知道這是否是特定設備?我目前正在使用三星GS3。 。 。

我DialogFragment:

// Runs the Apache Source Code in the Background 
private void launchApacheDialogFragment(FragmentManager fm,FragmentTransaction ft) 
{ 
    counter++; 

    // Check if the Dialog Already Exists 
    m_dialogFragment = (ApacheLicenseDialog) fm.findFragmentByTag(APACHE_FRAGMENT); 

    if(m_dialogFragment != null) 
    { 
     ft.remove(m_dialogFragment); 
    } 
    ft.addToBackStack(APACHE_FRAGMENT); 

    m_dialogFragment = ApacheLicenseDialog.newInstance(counter); 

    m_dialogFragment.show(fm, APACHE_FRAGMENT); 

} 

最後我的case語句調用該方法:

// Case 3 = Show the Apache Open Source License information 
     case 3: 

      // Launch the DialogFragment 
      launchApacheDialogFragment(fm, ft); 

      // Break out of the Statement 
      break; 

public class ApacheLicenseDialog extends DialogFragment implements Handler.Callback{ 

// Message Constants 
private static final int MSG_DO_WORK  = 0; 
private static final int MSG_START   = 1; 
private static final int MSG_DONE   = 2; 
private static final int MSG_SHUTDOWN  = 3; 

// UI Elements 
private TextView m_textApacheLicense  = null; 
private Button m_btnOk      = null; 
private ProgressBar m_apacheProgress  = null; 

// Background Processing Objects 
private BackgroundThread m_bgThread   = null; 
protected Handler m_handler     = null; 

// Apache String Object 
private String apacheLicense    = null; 

// ---------------------------------------------------------------------------- 
// New Instance Method invokes DialogFragment constructor 

public static ApacheLicenseDialog newInstance(int counter) 
{ 
    // Create the Apache License Dialog 
    ApacheLicenseDialog dialog = new ApacheLicenseDialog(); 

    Bundle data = new Bundle(); 
    data.putInt("Counter", counter); 
    Log.d("COUNTER", "New Instance called: "+ Integer.toString(counter)+" times."); 

    // Set the Arguments for the Dialog 
    dialog.setArguments(data); 

    // Return the Dialog 
    return dialog; 
} 

// --------------------------------------------------------------------------- 
// Class Overrides 

/* (non-Javadoc) 
* @see android.support.v4.app.DialogFragment#onCreate(android.os.Bundle) 
*/ 
@Override public void onCreate(Bundle savedInstanceState) 
{ 
    // Perform the Default Behavior 
    super.onCreate(savedInstanceState); 
    setRetainInstance(true); 

    // Create a new Handler, Background thread, and Start the Thread 
    m_handler = new Handler(this); 
    m_bgThread = new BackgroundThread(); 
    m_bgThread.start(); 
} 

/* 
* (non-Javadoc) 
* 
* @see 
* android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, 
* android.view.ViewGroup, android.os.Bundle) 
*/ 
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{ 
    // Set the Layout from XML Resource 
    return inflater.inflate(R.layout.apache_dialog_fragment, null); 
} 

/* 
* (non-Javadoc) 
* 
* @see 
* android.support.v4.app.DialogFragment#onActivityCreated(android.os.Bundle 
*) 
*/ 
@Override public void onActivityCreated(Bundle savedInstanceState) 
{ 
    // Perform Default Behavior 
    super.onActivityCreated(savedInstanceState); 

    // Reference this Dialog and Set its Title 
    getDialog().setTitle(getActivity().getResources().getString(R.string.text_Apache_License_Title)); 


    // Reference the UI Elements 
    m_textApacheLicense = (TextView) getView().findViewById(R.id.textViewApacheLicense); 
    m_apacheProgress = (ProgressBar) getView().findViewById(R.id.apacheProgress); 
    m_btnOk    = (Button)  getView().findViewById(R.id.btnOkay); 

    // Add a Listener to the Button 
    m_btnOk.setOnClickListener(OkListener); 

    // Starts the Message Sending 
    init(); 

} 

/* (non-Javadoc) 
* @see android.support.v4.app.DialogFragment#onDismiss(android.content.DialogInterface) 
*/ 
@Override public void onDismiss(DialogInterface dialog) 
{ 
    // Cleaned up this code, and Added some logging to test my message passing 
      m_bgThread.m_workerHandler.obtainMessage(MSG_SHUTDOWN).sendToTarget(); 

    Log.d("DISMISSING", "Dismissed called on ApacheLicenseDialog"); 


    try { 
     m_bgThread.join(); 
     Log.d("JOINING_THREAD", "Attempting to join the Thread"); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }finally{ 
     Log.d("JOINED_THREAD", "Thread successfully joined"); 
    } 

    // Perform the default behavior 
    super.onDismiss(dialog); 
} 

// ---------------------------------------------------------- 
// Handler.Callback Interface 

@Override public boolean handleMessage(Message msg) 
{ 
    switch(msg.what) 
    { 
    case MSG_START: 
     // Set the ProgressBar View to Visible 
     m_apacheProgress.setVisibility(View.VISIBLE); 
     break; 
    case MSG_DONE: 
     updateUI(msg); 
     break; 
    } 
    // return true 
    return true; 
} 

// --------------------------------------------------------------------------- 
// Private Class Method 

private void init() 
{ 
    // Send the Message to this Classes Handler 
    m_bgThread.m_workerHandler.obtainMessage(MSG_DO_WORK).sendToTarget(); 

} 

private void updateUI(Message msg) 
{ 
    // Set the ProgressBar View to Invisible 
    m_apacheProgress.setVisibility(View.INVISIBLE); 
    // Update the UI 
    m_textApacheLicense.setText(msg.obj.toString()); 
} 

private void obtainApacheLicense() 
{ 
    // Send message that the operation is Starting 
    m_bgThread.m_workerHandler.obtainMessage(MSG_START).sendToTarget(); 

    // Fetch the ApacheLicense 
    apacheLicense = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(getActivity()); 

    // Send Message the the operation is Done 
    m_handler.obtainMessage(MSG_DONE, apacheLicense).sendToTarget(); 
} 

// --------------------------------------------------------------------------- 
// Listeners 

private OnClickListener OkListener = new OnClickListener() 
{ 
    @Override public void onClick(View v) 
    { 
     // Dismiss the Dialog 
     dismiss(); 

    } 

}; 

// --------------------------------------------------------------------------- 
// BackgroundThread Class used to Fetch the Apache License from GooglePlayServicesUtil Class 

private class BackgroundThread extends Thread implements Handler.Callback{ 

    // Looper and Handler for the Background Thread 
    private Looper  m_workerLooper; 
    protected Handler m_workerHandler; 

    @Override public void run() 
    { 
     // Do background Processing 
     Looper.prepare(); 
     m_workerLooper = Looper.myLooper(); 
     m_workerHandler = new Handler(m_workerLooper, BackgroundThread.this); 
     Looper.loop(); 
    } 

    @Override public boolean handleMessage(Message msg) 
    { 
     switch(msg.what) 
     { 
     case MSG_DO_WORK: 
      // Run the obtainApacheLicenseFunction in this Thread 
      obtainApacheLicense(); 
      break; 
     case MSG_SHUTDOWN: 
      // Clean up the Looper by calling quit() on it 
      m_workerLooper.quit(); 
      Log.d("BACKGROUND_THREAD","Looper is shut down"); 
      break; 
     } 
     // Return true 
     return true; 
    } 

} 
} 

而且我用switch語句,例如顯示此任何幫助,將不勝感激,這是一種令人討厭的凍結拖延經驗,雖然它的只是爲了閱讀開源許可證。

再次請幫助我使用Thread/Handler/Looper思想。我試圖理解這個概念,而不是僅僅使用AsyncTask。

更新

我發現這個使用調試的角度來工作。我的線程啓動並且我的處理程序處理所有消息,並且在我的對話框片段的生命週期結束時後臺線程成功加入。我忘記了需要清理的東西嗎?

感謝

+0

我想我的問題在於我使用,以顯示該對話框的父活動。 。 。如果已經調用解僱,我該如何完全清理片段?還是我在做我需要做的一切? –

回答