如何从 main activity 调用非静态方法到片段?
How to call a non-static method from the main activity to a fragment?
我在片段中的侦听器从主 activity 调用非静态方法时遇到问题。 Android studio 提供了一种使方法静态化的解决方案,但这会中断程序的运行。
具体来说,我有一个包含多个按钮的不同片段。按下按钮时,它会激活后台进程以向 Arduino Web 服务器发送消息。这意味着该方法不能静态才能工作。
主要Activity.
package com.example.ethernettest1;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.ToggleButton;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabItem;
import com.google.android.material.tabs.TabLayout;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import static android.view.View.*;
public class MainActivity extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
private TabItem tab1, tab2, tab3;
public PagerAdapter pageradapter;
int dayNumber = 0;
int[] hourOpen = {0, 0, 0, 0, 0, 0, 0, 0};
int[] minutesOpen = {0, 0, 0, 0, 0, 0, 0, 0};
int[] hourClose = {0, 0, 0, 0, 0, 0, 0, 0};
int[] minutesClose = {0, 0, 0, 0, 0, 0, 0, 0};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabLayout = findViewById(R.id.tablayout);
tab1 = findViewById(R.id.Tab1);
tab2 = findViewById(R.id.Tab2);
tab3 = findViewById(R.id.Tab3);
viewPager = findViewById(R.id.viewpager);
pageradapter = new PageAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pageradapter);
//noinspection deprecation
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
if(tab.getPosition() == 0)
{
pageradapter.notifyDataSetChanged();
}
else if (tab.getPosition() == 1)
{
pageradapter.notifyDataSetChanged();
}
else if (tab.getPosition() == 2)
{
pageradapter.notifyDataSetChanged();
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
/*
Handle action bar item clicks here. The action bar will
automatically handle clicks on the Home/Up button, so long
as you specify a parent activity in AndroidManifest.xml.
*/
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/*****************************************************/
/* This is a background process for connecting */
/* to the arduino server and sending */
/* the GET request withe the added data */
/*****************************************************/
public class Background_get extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL("http://rolluiksturing.ddns.net/?" + params[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder result = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
result.append(inputLine).append("\n");
in.close();
connection.disconnect();
return result.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
还有一个碎片
package com.example.ethernettest1;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ToggleButton;
import androidx.fragment.app.Fragment;
/**
* A simple {@link Fragment} subclass.
*/
public class tab1 extends Fragment {
public tab1() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_tab1, container, false);
Button open = view.findViewById(R.id.open);
Button sluit = view.findViewById(R.id.sluit);
Button openAlles = view.findViewById(R.id.SelectAll);
Button sluitAlles = view.findViewById(R.id.DeselectAll);
Button naarBoven = view.findViewById(R.id.naarBoven);
Button naarOnder = view.findViewById(R.id.naarOnder);
ToggleButton Roluik1Button = view.findViewById(R.id.roluik1Button);
ToggleButton Roluik2Button = view.findViewById(R.id.roluik2Button);
ToggleButton Roluik3Button = view.findViewById(R.id.roluik3Button);
open.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
new MainActivity.Background_get().execute("Open");
else if (event.getAction() == MotionEvent.ACTION_UP) {
// Do nothing
}
return true;
}
});
sluit.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
new MainActivity.Background_get().execute("Sluit");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// Do nothing
}
return true;
}
});
openAlles.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
new MainActivity.Background_get().execute("OpenAlles");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// Do nothing
}
return true;
}
});
sluitAlles.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
new MainActivity.Background_get().execute("SluitAlles");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// Do nothing
}
return true;
}
});
naarBoven.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
new MainActivity.Background_get().execute("GaNaarBoven");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
new MainActivity.Background_get().execute("stop");
}
return true;
}
});
naarOnder.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
new MainActivity.Background_get().execute("GaNaarBeneden");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
new MainActivity.Background_get().execute("stop");
}
return true;
}
});
Roluik1Button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
new MainActivity.Background_get().execute("Zet1InArray");
} else {
new MainActivity.Background_get().execute("Zet1UitArray");
}
}
});
Roluik2Button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
new MainActivity.Background_get().execute("Zet2InArray");
} else {
new MainActivity.Background_get().execute("Zet2UitArray");
}
}
});
Roluik3Button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
new MainActivity.Background_get().execute("Zet3InArray");
} else {
new MainActivity.Background_get().execute("Zet3UitArray");
}
}
});
return inflater.inflate(R.layout.fragment_tab1, container, false);
}
}
好几篇文章都给出了与我需要的相反的答案,所以我希望有人能给我一个明确的答案。
您可以做的一件事是向您的 MainActivity 添加一个方法,如下所示
//note the following method
public void runBackgroundGet(String... params){
new Background_get().execute(params);
}
并让您的片段按如下方式调用它:
Roluik3Button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
(MainAticity(getActivity()).runBackgroundGet("Zet3InArray");
} else {
MainAticity(getActivity()).runBackgroundGet("Zet3UitArray");
}
}
});
但我必须警告你,使用 AsyncTask 会导致很多问题和泄漏,而且它们很快就会被标记为已弃用。我建议尝试使用视图模型和 Kotlin 协程来替换 AsyncTask。
:)
我在片段中的侦听器从主 activity 调用非静态方法时遇到问题。 Android studio 提供了一种使方法静态化的解决方案,但这会中断程序的运行。 具体来说,我有一个包含多个按钮的不同片段。按下按钮时,它会激活后台进程以向 Arduino Web 服务器发送消息。这意味着该方法不能静态才能工作。
主要Activity.
package com.example.ethernettest1;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.ToggleButton;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabItem;
import com.google.android.material.tabs.TabLayout;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import static android.view.View.*;
public class MainActivity extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
private TabItem tab1, tab2, tab3;
public PagerAdapter pageradapter;
int dayNumber = 0;
int[] hourOpen = {0, 0, 0, 0, 0, 0, 0, 0};
int[] minutesOpen = {0, 0, 0, 0, 0, 0, 0, 0};
int[] hourClose = {0, 0, 0, 0, 0, 0, 0, 0};
int[] minutesClose = {0, 0, 0, 0, 0, 0, 0, 0};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabLayout = findViewById(R.id.tablayout);
tab1 = findViewById(R.id.Tab1);
tab2 = findViewById(R.id.Tab2);
tab3 = findViewById(R.id.Tab3);
viewPager = findViewById(R.id.viewpager);
pageradapter = new PageAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pageradapter);
//noinspection deprecation
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
if(tab.getPosition() == 0)
{
pageradapter.notifyDataSetChanged();
}
else if (tab.getPosition() == 1)
{
pageradapter.notifyDataSetChanged();
}
else if (tab.getPosition() == 2)
{
pageradapter.notifyDataSetChanged();
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
/*
Handle action bar item clicks here. The action bar will
automatically handle clicks on the Home/Up button, so long
as you specify a parent activity in AndroidManifest.xml.
*/
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/*****************************************************/
/* This is a background process for connecting */
/* to the arduino server and sending */
/* the GET request withe the added data */
/*****************************************************/
public class Background_get extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL("http://rolluiksturing.ddns.net/?" + params[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder result = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
result.append(inputLine).append("\n");
in.close();
connection.disconnect();
return result.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
还有一个碎片
package com.example.ethernettest1;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ToggleButton;
import androidx.fragment.app.Fragment;
/**
* A simple {@link Fragment} subclass.
*/
public class tab1 extends Fragment {
public tab1() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_tab1, container, false);
Button open = view.findViewById(R.id.open);
Button sluit = view.findViewById(R.id.sluit);
Button openAlles = view.findViewById(R.id.SelectAll);
Button sluitAlles = view.findViewById(R.id.DeselectAll);
Button naarBoven = view.findViewById(R.id.naarBoven);
Button naarOnder = view.findViewById(R.id.naarOnder);
ToggleButton Roluik1Button = view.findViewById(R.id.roluik1Button);
ToggleButton Roluik2Button = view.findViewById(R.id.roluik2Button);
ToggleButton Roluik3Button = view.findViewById(R.id.roluik3Button);
open.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
new MainActivity.Background_get().execute("Open");
else if (event.getAction() == MotionEvent.ACTION_UP) {
// Do nothing
}
return true;
}
});
sluit.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
new MainActivity.Background_get().execute("Sluit");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// Do nothing
}
return true;
}
});
openAlles.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
new MainActivity.Background_get().execute("OpenAlles");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// Do nothing
}
return true;
}
});
sluitAlles.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
new MainActivity.Background_get().execute("SluitAlles");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// Do nothing
}
return true;
}
});
naarBoven.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
new MainActivity.Background_get().execute("GaNaarBoven");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
new MainActivity.Background_get().execute("stop");
}
return true;
}
});
naarOnder.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
new MainActivity.Background_get().execute("GaNaarBeneden");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
new MainActivity.Background_get().execute("stop");
}
return true;
}
});
Roluik1Button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
new MainActivity.Background_get().execute("Zet1InArray");
} else {
new MainActivity.Background_get().execute("Zet1UitArray");
}
}
});
Roluik2Button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
new MainActivity.Background_get().execute("Zet2InArray");
} else {
new MainActivity.Background_get().execute("Zet2UitArray");
}
}
});
Roluik3Button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
new MainActivity.Background_get().execute("Zet3InArray");
} else {
new MainActivity.Background_get().execute("Zet3UitArray");
}
}
});
return inflater.inflate(R.layout.fragment_tab1, container, false);
}
}
好几篇文章都给出了与我需要的相反的答案,所以我希望有人能给我一个明确的答案。
您可以做的一件事是向您的 MainActivity 添加一个方法,如下所示
//note the following method
public void runBackgroundGet(String... params){
new Background_get().execute(params);
}
并让您的片段按如下方式调用它:
Roluik3Button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
(MainAticity(getActivity()).runBackgroundGet("Zet3InArray");
} else {
MainAticity(getActivity()).runBackgroundGet("Zet3UitArray");
}
}
});
但我必须警告你,使用 AsyncTask 会导致很多问题和泄漏,而且它们很快就会被标记为已弃用。我建议尝试使用视图模型和 Kotlin 协程来替换 AsyncTask。
:)