Programming

활동 컨텍스트 외부에서 startActivity () 호출

procodes 2020. 3. 5. 08:02
반응형

활동 컨텍스트 외부에서 startActivity () 호출


ListView내 Android 응용 프로그램에서을 구현했습니다 . ListView클래스의 커스텀 서브 클래스를 사용하여 이것에 바인딩합니다 ArrayAdapter. 재정의 된 ArrayAdapter.getView(...)메서드 내에서을 할당합니다 OnClickListener. onClick방법 OnClickListener에서 새로운 활동을 시작하고 싶습니다. 나는 예외를 얻는다 :

Calling startActivity() from outside of an Activity  context requires the  
FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

(현재 )가 작동 하고 Context있다는 것을 어떻게 알 수 있습니까?ListViewActivity


어느 한 쪽

  • 어댑터의 생성자를 통해 Context 객체를 캐시하거나
  • 당신의 시야에서 그것을 얻으십시오.

또는 최후의 수단으로

  • FLAG_ACTIVITY_NEW_TASK 플래그를 의도에 추가하십시오.

_

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

편집-이벤트 및 기록 스택의 정상적인 흐름을 방해하므로 플래그 설정을 피하십시오.


대신 addFlags로 달성 할 수 있습니다.setFlags

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

설명서 에 따르면 다음과 같습니다.

의도에 (또는 기존 플래그 값으로) 추가 플래그를 추가하십시오.


편집하다

Alex Volovoy의 답변에서 알 수 있듯이 기록 스택을 변경하는 플래그를 사용하고 있는지 확인하십시오 .

... 이벤트 및 히스토리 스택의 정상적인 흐름을 방해하므로 플래그 설정을 피하십시오.


사용하는 대신 (getApplicationContext)사용YourActivity.this


아래와 같이 create chooser를 사용하여 오류가 발생한 경우 :

Intent sharingIntent = new Intent(Intent.ACTION_VIEW);
sharingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sharingIntent.setData(Uri.parse("http://google.com"));
startActivity(Intent.createChooser(sharingIntent, "Open With"));

다음과 같이 선택기를 작성하도록 플래그를 설정하십시오.

Intent sharingIntent = new Intent(Intent.ACTION_VIEW);
sharingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sharingIntent.setData(Uri.parse("http://google.com"));
Intent chooserIntent = Intent.createChooser(sharingIntent, "Open With");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(chooserIntent);

아마도 잘못된 위치에 OnClickListener를 구현하고 있다고 생각합니다. 보통 Activity에서 OnItemClickListener를 구현하고 대신 ListView에 설정해야합니다. 그렇지 않으면 이벤트에 문제가 발생합니다 ...


또한 : fragment의 listview에 링크를 표시하는 경우 다음 과 같이 만들지 마십시오

adapter = new ListAdapter(getActivity().getApplicationContext(),mStrings);

대신에 전화

adapter = new ListAdapter(getActivity(),mStrings);

어댑터는 두 경우 모두 잘 작동하지만 링크는 마지막 경우에만 작동합니다.


CustomAdapter mAdapter = new CustomAdapter( getApplicationContext(), yourlist);

또는

Context mContext = getAppliactionContext();
CustomAdapter mAdapter = new CustomAdapter( mContext, yourlist);

아래로 변경

CustomAdapter mAdapter = new CustomAdapter( this, yourlist);

일부 방법으로 listiner 내에서 의도를 작성하는 경우 참조

override onClick (View v).

그런 다음이보기를 통해 컨텍스트를 호출하십시오.

v.getContext ()

SetFlags도 필요하지 않습니다 ...


에이 점점 사람을 위해 Xamarin.Android (MonoDroid) startActivity를이 활동에서 호출해도 -이 새로운 ART 런타임에 자 마린 버그가 실제로 참조 https://bugzilla.xamarin.com/show_bug.cgi?id=17630


startactivity가 자신의 활동을 모르는 경우이 오류가 발생합니다. 따라서 startActivity () 전에 활동을 추가해야합니다

당신은 설정해야합니다

context.startActivity(yourIntent);

내 의견으로는, startActivity()코드에서의 방법을 사용하는 것이 좋습니다 Activity.class. 당신이에서 그것을 사용하는 경우 Adapter또는 다른 클래스, 그 발생합니다.


Alex Volovoy의 답변을 조금 더 정교하게-

조각 으로이 문제가 발생하는 경우 getActivity ()가 컨텍스트를 가져 오기 위해 잘 작동합니다.

다른 경우 :

사용하지 않으려면

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//not recommend

그런 다음 OutsideClass에서 이와 같은 함수를 만듭니다.

public void gettingContext(Context context){
    real_context = context;//where real_context is a global variable of type Context
}

이제 주 활동에서 새 OutsideClass를 작성할 때 활동의 컨텍스트를 인수로 제공하는 OutsideClass를 정의한 직후에 위의 메소드를 호출하십시오. 또한 주요 활동에서 기능을 수행하십시오.

public void startNewActivity(final String activity_to_start) {
    if(activity_to_start.equals("ACTIVITY_KEY"));
    //ACTIVITY_KEY-is a custom key,just to
    //differentiate different activities
    Intent i = new Intent(MainActivity.this, ActivityToStartName.class);
    activity_context.startActivity(i);      
}//you can make a if-else ladder or use switch-case

이제 OutsideClass로 돌아와서 새로운 활동을 시작하려면 다음과 같이하십시오.

@Override
public void onClick(View v) {
........
case R.id.any_button:

            MainActivity mainAct = (MainActivity) real_context;             
            mainAct.startNewActivity("ACTIVITY_KEY");                   

        break;
    }
........
}

이렇게하면 플래그를 엉망으로 만들지 않고 다른 OutsideClass에서 호출 된 다양한 활동을 시작할 수 있습니다.

참고-조각에 대한 생성자를 통해 컨텍스트 객체를 캐시하지 마십시오 (어댑터가 있으면 괜찮음) 조각에는 빈 생성자가 있어야합니다.

전화를 기억

OutsideClass.gettingContext(Context context);

onResume () 함수에서도.


나도 같은 문제가 있었다. 전달한 모든 컨텍스트를 확인하십시오. ' 링크 '의 경우 애플리케이션 컨텍스트가 아닌 활동 컨텍스트가 필요합니다 .

다음을 확인해야합니다.

1.) LayoutInflater사용한 경우 전달한 컨텍스트를 확인하십시오.

2.) 어댑터를 사용하는 경우 전달한 컨텍스트를 확인하십시오.


나는 같은 문제가 있었다. 문제는 맥락에 있습니다. 링크를 열려면 (예 : 선택기를 통해 링크 공유) 응용 프로그램 컨텍스트가 아닌 활동 컨텍스트를 전달하십시오.

활동 중이 myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)아닌 경우 추가 하는 것을 잊지 마십시오.


Adapter_Activity에서이 코드를 사용 context.startActivity(intent_Object)하고intent_Object.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

이처럼 :

Intent n_act = new Intent(context, N_Activity.class);
n_act.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(n_act);

효과가있다....


Intent viewIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);    
viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    
startActivity(viewIntent);   

이것이 효과가 있기를 바랍니다.


같은 문제에 직면 한 다음 구현

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

문제를 해결했습니다.

목록보기 어댑터와 관련된 다른 이유가있을 수 있습니다. 이 블로그를
살펴 보았습니다 .


이 코드를 사용하십시오. 나를 위해 잘 작동합니다. 활동 외에서 무언가 공유하기 :

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");

// Append Text
String Text = "Your Text Here"

intent.putExtra(Intent.EXTRA_TEXT, Text);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Intent shareIntent = Intent.createChooser(intent,"Share . . . ");
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
G.context.getApplicationContext().startActivity(shareIntent);

추가 플래그는 영향 때문에 event_flow그리고 stack_history당신이 다음과 같은 방법으로 활동 클래스를 호출 할 필요가있는 곳에서 비 활동으로 '애플리케이션 컨텍스트'를 통과하는 것이 좋습니다 :

"ActivityClassName.this"(이 방식으로 컨텍스트를 전달하는 동안 비 활동 시나리오에서 활동을 호출하는 데 필요한 모든 세부 사항 및 정보가 포함됨)

따라서 플래그를 설정하거나 추가 할 필요가 없으며, 모든 경우에 잘 작동합니다.


상기 Android 28(Android P)startActivity를

if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
        && (targetSdkVersion < Build.VERSION_CODES.N
                || targetSdkVersion >= Build.VERSION_CODES.P)
        && (options == null
                || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
    throw new AndroidRuntimeException(
            "Calling startActivity() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                    + " Is this really what you want?");
}

가장 좋은 방법은 추가입니다 FLAG_ACTIVITY_NEW_TASK

Intent intent = new Intent(context, XXXActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);

Intent i= new Intent(context, NextActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);

Cordova 플러그인 공유 의도를 호출하는 경우 플래그를 설정해도 도움이되지 않습니다. 대신 이것을 사용하십시오-

cordova.getActivity().startActivity(Intent.createChooser(shareIntent, "title"));

내 상황은 조금 달랐습니다. 사용하여 응용 프로그램을 테스트 하고 있으며 계측에서 ( Espresso내가 아닌) 내 활동을 시작해야했습니다 .ActivityTestRuleContextActivity

fun intent(context: Context) = 
    Intent(context, HomeActivity::class.java)
        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

플래그를 변경하고 or비트 단위 ( |Java로)를 추가해야했습니다.Intent.FLAG_ACTIVITY_NEW_TASK

결과는 다음과 같습니다.

fun intent(context: Context) = 
    Intent(context, HomeActivity::class.java)
        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)

코 틀린 버전

val intent = Intent(Intent.ACTION_EDIT, ContactsContract.Profile.CONTENT_URI)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
this.startActivity(intent)

참고 URL : https://stackoverflow.com/questions/3918517/calling-startactivity-from-outside-of-an-activity-context

반응형