简体   繁体   English

关于Android中的活动上下文和处理程序

[英]about activity context and handler in android

I am testing some stuff with handlers , and i came accross the following issue, the design og the classes itself i guess makes not much sense (passing the context of the activity to the constructor of the other class , which in turns extends Thread ), but i think it could be useful from the "academic" point of view. 我正在使用处理程序测试一些东西,遇到了以下问题,我认为类的设计本身没有多大意义(将活动的上下文传递给另一个类的构造函数,这反过来又扩展了Thread),但是我认为从“学术”的角度来看这可能是有用的。

so i have two class - the first one is activity , and the second one extends Thread , with the idea that the second class will pass some data to the activity , and i made a constructor which will take both the handlers from the activity and the context of that activity 所以我有两个类-第一个类是activity,第二个类是Thread的扩展,其思想是第二个类将一些数据传递给Activity,并且我构造了一个构造函数,该构造函数将同时使用该Activity和该活动的背景

PS. PS。 I found out that the Issue actually appears only when i try to pass the Location object parameters , edited the code: 我发现问题仅在我尝试传递Location对象参数并编辑代码时才出现:

the Activity part : 活动部分:

public class MainActivity extends Activity {





public static final String content="Asega kvo stava";
public static final Integer kom=2;
 Context m;


 private Handler nok;
 Location loc;

 String TAG="TAG";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    nok=new Handler() {

     public void handleMessage(Message msg)


    {





         Log.d(TAG, "msg: " + msg);
         Bundle m=msg.getData();




        }



    };


        new locac(nok,this).start();

and here is the other class 这是另一堂课

public class  locac   extends Thread implements LocationListener{

public static Context Ctx;
private final Handler nok; 
      LocationManager norm;

public static String moi="manag.GPS_PROVIDER";


public locac (Handler h, Context k){


    nok=h;
    Ctx=k;


}


.....

public void run ()


{
    norm=(LocationManager)Ctx.getSystemService(Ctx.LOCATION_SERVICE);
    norm.requestLocationUpdates(norm.GPS_PROVIDER, 0, 0, this);
    Location oko=norm.getLastKnownLocation(norm.GPS_PROVIDER);


          int lato=(int)oko.getLatitude();


  Message message=new Message();
              Bundle bok=new Bundle();


        int beta=145;

          bok.putInt("tok",lato);
          bok.putInt("toke",beta);
          message.setData(bok);
         nok.sendMessage(message)   ;
  }

now if i try to compile that one , it gives me the following message 现在,如果我尝试编译那个,它会给我以下消息

  java.lang.RuntimeException: Can't create handler inside thread that has not called 
  Looper.prepare()
at android.os.Handler.<init>(Handler.java:197)
at android.os.Handler.<init>(Handler.java:111)

if i remove the context part of the Constructor of the Locac, and leave it just 如果我删除Locac的构造函数的上下文部分,并将其保留

public locac (Handler h){


    nok=h;

}

and then just initialize it with - new locac(nok).start(); 然后只需使用-new locac(nok).start();对其进行初始化。 in the Activity class , then it works fine i can't figure why calling the context within the thread class gives the Looper message , a more detailed explanation will be greatly appreciated (for learning purposes also) 在Activity类中,然后工作正常,我无法弄清楚为什么在线程类中调用上下文会产生Looper消息,因此,非常详细的解释将不胜感激(也出于学习目的)

just in case anyone is interested , it turned out that the source of the problem was the requestLocationUpdates , which invokes the LocationListener object , which in turn calls the OnChangedLocation to get the updates 以防万一有人感兴趣,事实证明,问题的根源是requestLocationUpdates,它调用LocationListener对象,后者又调用OnChangedLocation获取更新。

if we look at the LocationManager.java 如果我们看一下LocationManager.java

public void onLocationChanged(Location location) {
        Message msg = Message.obtain();
        msg.what = TYPE_LOCATION_CHANGED;
        msg.obj = location;
        mListenerHandler.sendMessage(msg);
    }

which means the onLocationChanged calls the mListenerHandler and therefore the looper message.. 这意味着onLocationChanged会调用mListenerHandler并因此调用循环程序消息。

If you replace in your MainActivity new locac(nok,this).start(); 如果您在MainActivity中替换new locac(nok,this).start(); with new locac(nok,MainActivity.this); new locac(nok,MainActivity.this); you will not get the error, because when you use this you are referring to the Thread Object and not the MainActivity object. 您将不会得到该错误,因为使用此代码时 ,是指线程对象而不是MainActivity对象。 And you cannot pass a Thread Object into a Thread 而且您不能将线程对象传递给线程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM