主要和后台线程之间的android通信

时间:2014-06-24 12:05:45

标签: android multithreading handler

我需要从互联网上更新我的应用程序中的一些文件。为此,我可以启动新线程,检查Web服务器上的更新并向我的应用程序发出有关新更新的信号。 下面是我更新过程的骨架。此代码基于解释here

主要活动:

import android.os.Bundle;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity  implements TaskFragment.TaskCallbacks{
     TextView tvStatus;
     Button btnSend;
     private static final String TAG_TASK_FRAGMENT = "task_fragment";
     private TaskFragment mTaskFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvStatus = (TextView) findViewById(R.id.tvMain);
        FragmentManager fm = getFragmentManager();
        mTaskFragment = (TaskFragment) fm.findFragmentByTag(TAG_TASK_FRAGMENT);

        // If the Fragment is non-null, then it is currently being
        // retained across a configuration change.
        if (mTaskFragment == null) {
          mTaskFragment = new TaskFragment();
          fm.beginTransaction().add(mTaskFragment, TAG_TASK_FRAGMENT).commit();
        }
    }



    @Override
    public void onPostExecute(int msg) {
        // TODO Auto-generated method stub
        tvStatus.setText(""+msg);
         Toast.makeText(this, "Tere are new updates for You", Toast.LENGTH_LONG).show();
    }


}

工作片段以运行更新线程:

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Handler;

public class TaskFragment extends Fragment {
     private TaskCallbacks mCallbacks;
     Handler h;
    static interface TaskCallbacks {

        void onPostExecute(int msg);
      }
     @Override
      public void onAttach(Activity activity) {
        super.onAttach(activity);
        mCallbacks = (TaskCallbacks) activity;
      }

      /**
       * This method will only be called once when the retained
       * Fragment is first created.
       */
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Retain this fragment across configuration changes.
        setRetainInstance(true);
        h = new Handler() {
            public void handleMessage(android.os.Message msg) {
              mCallbacks.onPostExecute(msg.what);
          };
        };
        ////////////////////
        Thread t = new Thread(new Runnable() {
            public void run() {

              try {

                TimeUnit.SECONDS.sleep(20);
                while (true)//this is daemon thread
                {
                    if(this.checkUpddates())
                    {
                        h.sendEmptyMessage(1);
                    }
                    TimeUnit.SECONDS.sleep(2);// sleeping can be very long
                }


              } catch (InterruptedException e) {
                e.printStackTrace();
              }
            }

            private boolean checkUpddates() {
                //here check updates on internet
                try{
                    TimeUnit.SECONDS.sleep(2);// emulate check updates work

                }
                } catch (InterruptedException e) {
                e.printStackTrace();
              }
                                return true;
            }

          });
        t.setDaemon(true);
          t.start();

      }

      /**
       * Set the callback to null so we don't accidentally leak the 
       * Activity instance.
       */
      @Override
      public void onDetach() {
        super.onDetach();
        mCallbacks = null;
      }

}

XML布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world"
     android:id="@+id/tvMain" />

此代码在我尝试旋转屏幕时工作正常。它也适用于我在另一个活动中工作而不是主活动和更新线程将其结果返回到Handler的handleMessage方法。 我想请求android guru建议我,如果我在正确的方式或可能有更好的方法来执行此任务?我的代码中有任何陷阱吗?

1 个答案:

答案 0 :(得分:0)

在我的情况下,我会采用不同的方法。如果您需要刷新Feed(类似于Tweeter),我会使用onCreate()为后台操作触发单个请求AsyncTask。如果您需要每20秒自动刷新一次数据,则只需添加一个计时器即可重新激活AsyncTask。这样您就可以与AsyncTask#onPostExecute()

中的UI线程进行通信

如果您需要的是持久连接,导致您发送和检索实时数据(例如聊天应用),那么您可能希望使用Socket进行Thread实施与你正在做的相似。

在这两种情况下,我都看到使用Fragment是不必要的,但我可能错了。