使用线程/处理器/尺蠖的工作线程的Andr​​oid [英] Using Thread/Handler/Looper for Worker Thread Android

查看:218
本文介绍了使用线程/处理器/尺蠖的工作线程的Andr​​oid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

执行线程时/处理器/尺蠖意识形态通过传递消息来处理背景资料有一些响应的问题。我真的不希望使用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

这篇关于使用线程/处理器/尺蠖的工作线程的Andr​​oid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆