使用线程/处理器/尺蠖的工作线程的Android [英] Using Thread/Handler/Looper for Worker Thread Android
问题描述
执行线程时/处理器/尺蠖意识形态通过传递消息来处理背景资料有一些响应的问题。我真的不希望使用AsyncTask的类,因为我已经知道如何用它来完成我想做的事情。
Having some responsiveness issues when implementing the Thread/Handler/Looper ideology to process information in the background by passing messages. I really don't want to use the AsyncTask class, since i already know how to use that to accomplish what I am trying to do.
有人可以帮助我用下面的code,用于下载使用GooglePlayServicesUtil类Apache许可证,并显示在一个TextView一个DialogFragment里面呢?
Can someone help me with the following code that downloads the Apache License using the GooglePlayServicesUtil class and displays it in a TextView inside a DialogFragment ?
我的最大的问题是,当我启动它,有时是快,但别人是展现DialogFragment很慢。也许我没有按照最佳做法装载DialogFragment,我真的不知道。
My biggest issue is that when i launch it, sometimes it is fast but others it is very slow to show the DialogFragment. Maybe I am not following the best practice for loading the DialogFragment, i don't really know.
更新
增加了code即现在的工作,但由于某些原因我还是在一段时间获得一个UI冻结一次。
有谁知道这是特定设备?我目前三星GS3。 。
Update Added code that is now working, but for some reason I still get a UI Freeze once in a while. Does anyone know if this is device specific? I am currently on a Samsung GS3. . .
我DialogFragment:
My DialogFragment:
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语句这样:
And i show this by using a switch statement as such:
// 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语句:
And finally my case statement which calls this method:
// Case 3 = Show the Apache Open Source License information
case 3:
// Launch the DialogFragment
launchApacheDialogFragment(fm, ft);
// Break out of the Statement
break;
任何帮助将是AP preciated,这是一种恼人的冻结延缓了经验,虽然它只是读取开源许可。
Any help would be appreciated, this is kind of an annoying freeze delaying the experience, although its just to read the open source license.
再次请使用线程/处理器/尺蠖思想帮助我。我试图理解这个概念,而不是只用AsyncTask的。
Again, please help me using the Thread/Handler/Looper ideology. I am trying to understand this concept as opposed to just using AsyncTask.
更新
我发现这个使用调试的角度来工作。我的线程启动了,我的处理程序处理所有的消息,并在我的对话片段的生命周期中的后台线程成功加入的结束。我忘记一些需要清理吗?
I have found this to be working using Debug perspective. My thread starts up and my handler processes all the messages and at the end of the lifecycle of my dialog fragment the background thread successfully joins. Am i forgetting something that needs to be cleaned up more?
感谢
推荐答案
我找到了一个更好的方式来做到这一点使用一个BroadcastReceiver这里<一见的帖子href=\"http://stackoverflow.com/questions/22690509/programmatically-registering-child-class-broadcastreceiver-onreceivecontext-in\">Programmatically注册子类的BroadcastReceiver的onReceive(上下文,意图)没有得到所谓的DialogFragment
I found a better way to do this using a BroadcastReceiver see the post here Programmatically Registering Child Class BroadcastReceiver onReceive(context, intent) not getting called in DialogFragment
这篇关于使用线程/处理器/尺蠖的工作线程的Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!